Repository navigation
First press-and-hold after idle records nothing: transient mic reopen failure suspends the in-flight hotkey gesture #130
Description
HEX version
2.1.25 (signed DMG, CFBundleVersion 20125)
Platform
macOS
System details
macOS 26.6.2 (build 25G83), MacBook Pro Mac15,6 (Apple M3 Pro, 18 GB)
What happened?
With the dictation hotkey bound to a modifier-only chord (right shift) and Microphone mode set to "Release when idle", the first press-and-hold after the app has been idle records nothing. The indicator flashes, the error tone plays, and no text is pasted. Releasing and pressing again records normally.
Expected: the hold records, or at worst the first press recovers within itself rather than being thrown away.
Steps to reproduce
- Settings: dictation hotkey = right shift (modifier-only), double-tap lock enabled, Microphone mode = "Release when idle".
- Leave Hex idle for a few minutes. All observed failures required the capture device to have been closed for >=146 s.
- Press and hold the hotkey and speak.
- Observed: the capture aborts ~150 ms in, error tone, no output.
- Release and press again: records normally.
Evidence
Redacted excerpts from process.log:
WARN voice_control::audio: selected microphone is unavailable; using automatic selection
INFO voice_control::audio: dictation microphone reopened device=<redacted>
ERROR voice_control::audio: microphone stream failed error=A buffer underrun or overrun occurred.
WARN voice_control::audio: microphone stream stopped; reopening it
The matching entries in live.ndjson:
17:01:23.810 dictation started
17:01:23.964 dictation {"failed": "Microphone capture was interrupted; reconnecting."}
Aggregate over roughly five weeks of logs (about 770 captures):
- 34
microphone stream failedevents, 33 of which surfaced as a failed dictation readingMicrophone capture was interrupted; reconnecting. - Every one of them followed the capture device being closed for >=146 s (min 146.5 s, median about 50 minutes). Zero failures occurred below that.
- 624 reopens succeeded, 93 of them with under 5 s idle, so reopening is normally fine; the cold open is what is fragile.
- Each aborted session ends 20-76 ms after its own
dictation microphone reopenedline, so how long the user held the key has no bearing on when it ends.
Suspected cause
src/recognition.rs handles DictationAudioEvent::Interrupted by calling abandon_capture(), which calls hotkeys.suspend_all(). That discards the gesture the user is still holding, so the subsequent release is a no-op. The recovery machinery already exists (backoff in MicrophoneRecovery in src/audio.rs, pending_capture re-armed on Reopened in src/dictation_audio.rs), but the hotkey gesture does not survive the interruption.
Possible fix: on an interruption during a hotkey capture, keep the gesture alive (do not suspend_all) and re-arm the pending capture when the device reopens, letting the existing 250 ms to 5 s backoff recover inside the same press.
Additional context
Workaround: setting Microphone mode to "Keep ready (fast)" removes the cold open and the symptom stops.
Possibly related: #54.
One separate observation, explicitly unverified. Of presses taken after >=300 s idle, 44% are short (<0.35 s) and are discarded by the 300 ms MINIMUM_HOLD_DURATION, versus 14-20% at short idle. Those session ends do not track the microphone reopen, and their distribution looks identical at short and long idle. I could not separate "the user tapped" from the state machine discarding the hold (the HotkeyAction::Discard arm in src/suppression.rs), because the logs carry no raw input events and there is no tracing::debug! anywhere in the input path. Mentioning it in case it shares a cause with #54.
Activity
feat: Hex 2.2.0 — faster dictation and the Meetings beta (#133)
kitlangton commentedon Oct 18, 2026
This should be fixed in 2.2.0, which just shipped. When the microphone glitches while reopening after idle, Hex now keeps your held press and reopens the mic instead of discarding the capture.
I'm closing this for now. If you still see the first hold after idle record nothing on 2.2.0, please reopen with the new
process.logexcerpt.