fix(notifications): guard UN calls when running unbundled (fixes tauri dev crash) - #38
Merged
Merged
Conversation
`UNUserNotificationCenter` dereferences `NSBundle.mainBundle` and throws `NSInternalInconsistencyException: bundleProxyForCurrentProcess is nil` when the executable is launched directly (e.g. `pnpm run tauri dev`, which runs `target/debug/meetily` rather than the bundled `.app`). Since commits #32/#33 migrated macOS notifications from the legacy `NSUserNotification` path to UN, every `tauri dev` run crashes at startup. Skip the UN calls when `current_exe()` has no `.app` ancestor. `request_authorization` returns `Err` (not `Ok(false)`) so `manager.rs` falls into its existing `Err` arm and does not persist `system_permission_granted = false` — the dev run and the bundled `.app` share `~/Library/Application Support/com.meetily.ai/`, so persisting `false` would silently suppress every real notification until the user re-granted consent. `show()` returns `Ok(())`; callers do not store state on success. Bundled `.app` behavior is unchanged.
AzimovS
added a commit
that referenced
this pull request
Apr 24, 2026
Prepares a release containing the work merged since v0.1.15: - feat(detection): mic-activity meeting auto-detection on macOS (#35) - feat(transcription): retry with backoff + in-transcript failure placeholder (#39) - feat(summary): TownHall template (#30), current template name in dropdown (#31), specificity prompt tweak (#37) - feat(remote): test-connection button + model selection surface improvements (#28, #29) - fix(notifications): migrate to UNUserNotificationCenter (#32), SAFETY + fallback race fixes (#33), unbundled-dev crash guard (#38), drop OS recording banners and flip auto_save default to false (#36) - chore(about): drop Zackriya services CTA (#40) Behavior change to call out in release notes: fresh installs (and users with no stored recording_preferences.json) now default auto_save to false — audio files are not written to disk unless the user opts in via Recording Settings. Existing users with saved preferences are unaffected. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pnpm run tauri dev/./clean_run.shcrashes at startup on macOS with:Commits #32 / #33 migrated macOS notifications from
tauri-plugin-notification(legacyNSUserNotification, which delivers on unbundled binaries but no longer fires banners on modern macOS) toUNUserNotificationCenter. The modern UN API dereferencesNSBundle.mainBundleand throws when the executable was launched directly rather than from a.appbundle.tauri devrunstarget/debug/meetily(not the bundled.app), so UN crashes the app before the window even opens.Fix
Add an
is_running_in_app_bundle()guard infrontend/src-tauri/src/notifications/macos_un.rsthat checks whethercurrent_exe()has a*.appancestor, and early-return from the two UN entry points when unbundled.Two subtleties worth calling out:
request_authorizationreturnsErr, notOk(false).manager.rs:60-62persists the result viaset_system_permission(granted). Dev runs and the bundled.appshare the same config directory (~/Library/Application Support/com.meetily.ai/notification_settings.json), so returningOk(false)would writesystem_permission_granted = falseto disk and silently suppress every real notification in the shipped app until the user manually re-granted consent. ReturningErrhits the existingErrarm atmanager.rs:69-72which logs and continues without persisting — no cross-build poisoning.show()returnsOk(()). Callers propagate theResultupward but do not store state on success, so a silent no-op is safe in dev.Bundled
.appbehavior is unchanged — the guard only fires when the ancestor walk finds no.app.Test plan
cargo checkclean./clean_run.sh(=pnpm run tauri dev) on macOS: app starts; logs showUN authorization skipped: not running inside a .app bundle (likely \tauri dev`)followed byNotification system initialized successfully`. No crash..app(pnpm run tauri:buildor./clean_build.sh) and launch it directly → first-run macOS permission prompt appears; test notifications fire as banners.system_permission_grantedin~/Library/Application Support/com.meetily.ai/notification_settings.jsonis not overwritten by atauri devrun.Known follow-ups (intentionally out of scope)
system.rssomacos_un.rsstays a pure UN transport.tauri-plugin-notificationso devs get some banner delivery duringtauri dev(at the cost of keeping the legacy dep on macOS).NSBundle.mainBundle.bundleIdentifier().is_some()for a more authoritative signal.