# swift-macos-client-debug > Debug and fix Swift macOS menubar app issues including code signing crashes, MainActor isolation errors, and app termination. Use when the client app won't launch, crashes on startup, shows code signature errors, or has threading/concurrency issues. - Author: thegaltinator - Repository: thegaltinator/Alfred - Version: 20260130193846 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/thegaltinator/Alfred - Web: https://mule.run/skillshub/@@thegaltinator/Alfred~swift-macos-client-debug:20260130193846 --- --- name: swift-macos-client-debug description: Debug and fix Swift macOS menubar app issues including code signing crashes, MainActor isolation errors, and app termination. Use when the client app won't launch, crashes on startup, shows code signature errors, or has threading/concurrency issues. --- # Swift macOS Client Debugging Guide When the Alfred macOS client (client-prod) isn't working, follow this systematic debugging approach. ## Quick Diagnosis Checklist 1. **Check crash reports**: `ls -t ~/Library/Logs/DiagnosticReports/Alfred*` 2. **Check if running**: `ps aux | grep Alfred | grep -v grep` 3. **Run directly**: `/path/to/Alfred.app/Contents/MacOS/Alfred 2>&1` 4. **Verify signature**: `codesign -vvv /path/to/Alfred.app` ## Common Issues & Fixes ### 1. Code Signature Invalid (SIGKILL) **Symptoms:** - App crashes immediately on launch - Crash report shows: `"signal":"SIGKILL (Code Signature Invalid)"` - Termination namespace: `CODESIGNING`, indicator: `Invalid Page` **Fix - Add required entitlements** to `Alfred.entitlements`: ```xml com.apple.security.cs.disable-library-validation com.apple.security.cs.allow-unsigned-executable-memory ``` **Fix - Fresh bundle ID** (avoid cache issues): ```bash # In build-app.sh, change: BUNDLE_ID="com.bicyclelabs.alfred3-dev" # Use unique ID ``` **Fix - Remove quarantine and re-sign**: ```bash xattr -cr /path/to/Alfred.app codesign --force --deep --sign - --entitlements Alfred.entitlements /path/to/Alfred.app ``` ### 2. MainActor Isolation Errors **Symptoms:** - Build errors: `cannot be called from outside of the actor` - Runtime crashes with threading violations **Fix - Wrap calls in MainActor context**: ```swift // From async context: await MainActor.run { UserSession.shared.clearUser() } // From sync context: Task { @MainActor in UserSession.shared.clearUser() } ``` **Common files needing fixes:** - `TalkerService.swift` - UserSession calls in actor methods - `DeviceAuthService.swift` - UserSession calls in sync methods - `AlfredApp.swift` - Notification observer closures ### 3. App Terminates Immediately **Symptoms:** - App starts, logs appear, then `👋 Alfred app terminating` - No crash report generated **Fix - Add `applicationShouldTerminateAfterLastWindowClosed`**: ```swift // In AppDelegate func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return false // CRITICAL for menubar apps } ``` **Fix - Mark AppDelegate as @MainActor**: ```swift @MainActor class AppDelegate: NSObject, NSApplicationDelegate { // ... } ``` ### 4. Framework Loading Failures **Symptoms:** - Crashes in dyld during startup - "Library not found" errors **Fix - Verify framework paths**: ```bash # Check what the executable expects otool -L /path/to/Alfred.app/Contents/MacOS/Alfred # Fix paths if needed install_name_tool -add_rpath "@executable_path/../Frameworks" /path/to/Alfred.app/Contents/MacOS/Alfred install_name_tool -change "@rpath/whisper.framework/Versions/A/whisper" "@executable_path/../Frameworks/whisper.framework/Versions/A/whisper" /path/to/Alfred.app/Contents/MacOS/Alfred ``` ### 5. Whisper Framework Signing **The whisper.framework has a non-standard layout. Sign in this order:** ```bash # 1. Sign dylibs in Libraries/ first for dylib in Alfred.app/Contents/Frameworks/whisper.framework/Versions/A/Libraries/*.dylib; do codesign --force --sign - "$dylib" done # 2. Sign the versioned binary codesign --force --sign - Alfred.app/Contents/Frameworks/whisper.framework/Versions/A/whisper # 3. Sign the framework bundle codesign --force --sign - Alfred.app/Contents/Frameworks/whisper.framework # 4. Sign Sparkle codesign --force --deep --sign - Alfred.app/Contents/Frameworks/Sparkle.framework # 5. Sign the app codesign --force --deep --sign - --entitlements Alfred.entitlements Alfred.app ``` ## Clean Build Process When things aren't working, do a completely fresh build: ```bash # 1. Clean all caches rm -rf client-prod/.build rm -rf client-prod/.swiftpm rm -rf client-prod/dist rm -rf ~/Library/Developer/Xcode/DerivedData/*Alfred* rm -rf ~/Library/Caches/com.bicyclelabs.alfred* # 2. Update bundle ID to avoid stale cache # Edit scripts/build-app.sh: BUNDLE_ID="com.bicyclelabs.alfred-fresh" # 3. Build fresh cd client-prod bash scripts/build-app.sh # 4. Remove quarantine xattr -cr dist/Alfred.app # 5. Launch open dist/Alfred.app ``` ## Required Entitlements for Ad-Hoc Signing ```xml com.apple.security.app-sandbox com.apple.security.network.client com.apple.security.device.audio-input com.apple.security.cs.disable-library-validation com.apple.security.cs.allow-unsigned-executable-memory ``` ## Key Files | File | Purpose | |------|---------| | `client-prod/Alfred.entitlements` | Code signing entitlements | | `client-prod/scripts/build-app.sh` | Build script with bundle ID | | `client-prod/AppKitUI/AlfredApp.swift` | App lifecycle, StatusBar | | `client-prod/Bridge/UserSession.swift` | Thread-safe session state | | `client-prod/Bridge/TalkerService.swift` | Server communication | | `client-prod/Bridge/DeviceAuthService.swift` | OAuth flow | ## Verification Commands ```bash # Check signature codesign -vvv /path/to/Alfred.app # Check Gatekeeper (will fail for ad-hoc, that's OK) spctl -a -vvv /path/to/Alfred.app # Check if running ps aux | grep Alfred | grep -v grep # View crash reports ls -t ~/Library/Logs/DiagnosticReports/Alfred* | head -5 # Read latest crash cat $(ls -t ~/Library/Logs/DiagnosticReports/Alfred* | head -1) ```