[BUG] Claude Desktop (macOS) main thread deadlocks in swift_addon.node posting a UNUserNotification; whole app locks when a Code tab terminal command finishes
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Desktop on macOS locks up completely. The window cannot be moved or force-redrawn, and there is no spinning beachball because the app stops processing events entirely. Force quit is the only way out.
The trigger that reproduces it reliably: in the Code tab, run a shell command via the integrated terminal panel. The command completes, and the app freezes at the moment it would post the "done" notification.
A sample of the hung process shows the main thread blocked synchronously inside swift_addon.node on -[UNUserNotificationCenter addNotificationRequest:withCompletionHandler:], waiting on the com.apple.usernotifications.UNUserNotificationServiceConnection queue. That queue is itself blocked inside swift_addon.node NotificationService.close(id:) doing a synchronous XPC round trip for removePendingNotificationRequestsWithIdentifiers:. A third thread is also blocked in NotificationService.close(id:) on removeDeliveredNotificationsWithIdentifiers:. This looks like a lock-order deadlock between posting a new notification and closing old ones, with the main thread caught in the middle.
Before finding this, I had already: cleared caches, uninstalled and reinstalled the app, renamed ~/Library/Application Support/Claude and ~/Library/Caches/com.anthropic.claudefordesktop to start fresh. None of that changed anything, which is consistent with the hang being in native notification code rather than app state.
Earlier in the day the same app was also freezing mid-response in the Code tab without any terminal use, which may be the same path (a notification fired on task completion).
What Should Happen?
Posting or clearing a macOS notification should never block the main thread. The app should stay responsive after a terminal command completes.
Error Messages/Logs
Key frames from sample Claude 10 (full file attached as claude-hang.txt):
Thread_2955625 DispatchQueue_1: com.apple.main-thread (serial)
completeTaskWithClosure (in libswift_Concurrency.dylib)
??? (in swift_addon.node) load address 0x14c610000 + 0x67cb1
??? (in swift_addon.node) ... + 0xd22d1 / 0xdac19 / 0xd8e2d / 0x6b251 / 0x69ed1 / 0x1d885 / 0xdc5f4
-[UNUserNotificationCenter addNotificationRequest:withCompletionHandler:] (in UserNotifications) + 208
-[UNUserNotificationServiceConnection addNotificationRequest:forBundleIdentifier:withCompletionHandler:] + 648
_dispatch_sync_f_slow
__DISPATCH_WAIT_FOR_QUEUE__
_dispatch_event_loop_wait_for_ownership
_dispatch_kq_poll
kevent_id
Thread_2992008 DispatchQueue_815: com.apple.usernotifications.UNUserNotificationServiceConnection (serial)
completeTaskWithClosure (in libswift_Concurrency.dylib)
??? (in swift_addon.node) ... + 0x67cb1 / 0xd22d1 / 0xdac19 / 0xd8e2d / 0x6aea1 / 0x6a264
NotificationService.close(id:) (in swift_addon.node) + 260
-[UNUserNotificationCenter removePendingNotificationRequestsWithIdentifiers:] + 80
-[UNUserNotificationServiceConnection removePendingNotificationRequestsWithIdentifiers:forBundleIdentifier:completionHandler:] + 372
_dispatch_lane_barrier_sync_invoke_and_complete
__NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__
xpc_connection_send_message_with_reply_sync
mach_msg2_trap
Thread_3003763 DispatchQueue_18: com.apple.root.user-initiated-qos.cooperative (concurrent)
completeTaskWithClosure (in libswift_Concurrency.dylib)
??? (in swift_addon.node) ... + 0x67cb1 / 0xd22d1 / 0xdac19 / 0xd8e2d / 0x6aea1 / 0x6a264
NotificationService.close(id:) (in swift_addon.node) + 168
-[UNUserNotificationCenter removeDeliveredNotificationsWithIdentifiers:] + 80
-[UNUserNotificationServiceConnection removeDeliveredNotificationsWithIdentifiers:forBundleIdentifier:completionHandler:] + 372
_dispatch_sync_f_slow
__DISPATCH_WAIT_FOR_QUEUE__
kevent_id
All three stacks held for the entire 10 second sample (6885/6885 samples).
Steps to Reproduce
- Open Claude Desktop on macOS, go to the Code tab, open a project folder.
- Open the integrated terminal panel and run any shell command (even one that fails, e.g.
cd nonexistent). - When the command completes, the app freezes. Window cannot be moved, no beachball, no crash report in
~/Library/Logs/DiagnosticReports. sample Claude 10 -f ~/Desktop/claude-hang.txtfrom Terminal.app shows the stacks above.
Environment
- Claude Desktop: 1.52386.3 (com.anthropic.claudefordesktop)
- Code Type: ARM64
- macOS: 26.6.2 (25G83)
- Bundled Claude Code (Code tab), not the CLI. The standalone CLI (2.1.269, native install) works fine in Terminal.app.
- Plan: Max
- Physical footprint at hang: 207 MB (peak 482 MB), so not memory pressure.
Additional Information
The swift_addon.node frames are unsymbolicated in the sample (???), but NotificationService.close(id:) is symbolicated, so the addon's notification module is clearly involved on all three threads.
Since the main thread is calling addNotificationRequest in a way that ends up in _dispatch_sync_f_slow, it appears the completion is being awaited synchronously on the main actor. Moving the notification post and the close/remove calls fully async, or serializing them on one queue that never blocks main, should resolve it.
What Should Happen?
No lock ups.
Error Messages/Logs
Steps to Reproduce
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.269 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Been happening for a while. Usually beachballs. Sometimes just a hard lock. Can't move window, can't select anything. Have to force quit with opt+cmd+esc.