[BUG] Claude Desktop (macOS) main thread deadlocks in swift_addon.node posting a UNUserNotification; whole app locks when a Code tab terminal command finishes

Status Open
Reported on v2.1.269
Maintainer reply None cached
Activity 0 comments · opened Sep 12, 2026

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

  1. Open Claude Desktop on macOS, go to the Code tab, open a project folder.
  2. Open the integrated terminal panel and run any shell command (even one that fails, e.g. cd nonexistent).
  3. When the command completes, the app freezes. Window cannot be moved, no beachball, no crash report in ~/Library/Logs/DiagnosticReports.
  4. sample Claude 10 -f ~/Desktop/claude-hang.txt from 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-hang.txt

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.

View original on GitHub ↗