Skip to content

Open even when macOS's audio service is stuck; 0.16.10 - #25

Merged
belugaming merged 1 commit into
mainfrom
claude/audio-service-stall
Oct 27, 2026
Merged

belugaming merged 1 commit into
mainfrom
claude/audio-service-stall

Conversation

@belugaming

Copy link
Copy Markdown
Owner

ClassNote spun forever at launch whenever macOS's audio service, coreaudiod, was deadlocked. The hang reports showed the main thread waiting on coreaudiod inside AppState.bootstrap() → MicrophoneDeviceCatalog.availableInputDevices(), while coreaudiod itself was deadlocked: an audio plug-in device was changing (an iPhone Continuity microphone arriving, a virtual audio driver re-registering) while a system audio tap was running. The deadlock is a macOS bug. ClassNote's part was asking for the device list on the main thread.

What changed

  • AppState.refreshMicrophoneDevices() now runs the Core Audio query on a GCD thread, one query at a time. The list starts as "System default" until the answer arrives.
  • If coreaudiod has not answered within 5 seconds:
    • isAudioServiceUnresponsive is set and the app keeps working (library, notes, search).
    • Starting a recording or live translation is refused with an explanation, because capture would freeze the app the same way. The message says to restart the Mac or run sudo killall coreaudiod.
    • Settings → Audio input and Diagnostics show the same message.
  • A late answer, from a daemon that was stuck or has just been restarted, no longer makes the app forget the chosen microphone.
  • selectedMicrophoneName, which the menu bar reads on every redraw, comes from the loaded list only and never asks Core Audio.

Testing

  • New AudioServiceStallTests covers three cases: a query that never returns does not block the main actor and blocks recording; only a prompt answer drops a missing microphone; the selected name comes from the loaded list.
  • Full suite passes locally on macOS 27.2 / Xcode 27: 205 tests.
  • Tried on the affected Mac while coreaudiod was still deadlocked: the fixed build opened its window and the main thread stayed idle, with the stuck query parked on a background thread.

Version 0.16.10 (build 28).

🤖 Generated with Claude Code

ClassNote spun forever at launch whenever coreaudiod was deadlocked (a macOS bug: seen on 27.2 when an audio plug-in device changed while a system audio tap was running). Bootstrap listed the microphones on the main thread, and that Core Audio query never returned, so the window never drew.

The microphone list now loads on a background thread, one query at a time. If coreaudiod has not answered within 5 seconds the app still opens and the library works; starting a recording is refused with an explanation (restart the Mac or run "sudo killall coreaudiod") instead of freezing the app. Settings and Diagnostics show the same message. A late answer no longer makes the app forget the chosen microphone, and the menu bar's microphone name is read from the loaded list instead of asking Core Audio on every redraw.

Version 0.16.10 (build 28).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@belugaming
belugaming merged commit 69bd53f into main Oct 27, 2026
4 checks passed
@belugaming
belugaming deleted the claude/audio-service-stall branch October 27, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant