[BUG] Voice hold-to-talk stops mid-hold on macOS: 200 ms release timeout is shorter than real key-repeat gaps (0.5–1.4 s)
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?
Hold-to-talk voice mode stops recording while space is still held. I have to press space again to keep talking. It happens several times a minute, more often when several Claude Code sessions are busy.
Cause, as far as I can measure: terminals get no key-release event, so hold mode infers "released" when no auto-repeated space arrives within 200 ms. macOS does not deliver key repeat that evenly. Repeats normally arrive every ~84 ms, but there are regular gaps of 0.5–1.4 s while the key is held down the whole time. Each gap ends the recording.
I measured the gaps with a small raw-mode stdin probe (script below) while holding space for ~5 s at a time:
| Setup | repeats | p50 | p95 | max | gaps > 200 ms |
|---|---|---|---|---|---|
| Superset terminal, Bluetooth keyboard | 118 | 84 ms | 498 ms | 1210 ms | 7 |
| Terminal.app, Bluetooth keyboard | 124 | 84 ms | 86 ms | 961 ms | 4 |
| Terminal.app, MacBook built-in keyboard, Bluetooth off | 90 | 84 ms | 86 ms | 1441 ms | 2 |
| Terminal.app, Bluetooth keyboard, Raycast quit | 165 | 84 ms | 86 ms | 1086 ms | 4 (1086, 494, 890, 500 ms) |
The gaps occur in every terminal, with the built-in keyboard, and with Raycast (the only keyboard-hook app running) quit. So any terminal on a loaded Mac will sometimes exceed a 200 ms threshold.
What Should Happen?
Holding space should keep recording until I let go, as long as auto-repeat resumes. Some options:
- Raise the release timeout, or make it adaptive (for example, a multiple of the observed repeat interval, with a floor well above 200 ms).
- Use real key-release events where the terminal supports them (kitty keyboard protocol with event types, flag 2).
- After a release that may have been a gap, keep the session open briefly, so the next repeat continues the same recording instead of starting a new one.
Error Messages/Logs
No error is shown. The recording just stops ("[voice] finishRecording" fires from the release timer while the key is still down).
Steps to Reproduce
- Enable
/voicein hold mode (the default) on macOS. - Run 2–3 other busy Claude Code sessions so the machine is under load.
- Hold space and talk for 20–30 s.
- Recording stops partway, usually several times.
To measure the repeat gaps directly, run this in any terminal, hold space ~5 s, release, and repeat (Ctrl-C to quit):
// space-gap-probe.mjs: run with `node space-gap-probe.mjs`
process.stdin.setRawMode(true);
process.stdin.resume();
let last = 0, first = true, gaps = [];
process.stdin.on("data", (buf) => {
for (const b of buf) {
if (b === 3) { report(); process.exit(0); }
if (b !== 0x20) continue;
const now = performance.now();
if (last && now - last < 1500) { if (first) first = false; else gaps.push(now - last); }
else { report(); first = true; }
last = now;
}
});
function report() {
if (!gaps.length) return;
const s = [...gaps].sort((a, b) => a - b);
const p = (q) => s[Math.min(s.length - 1, Math.floor(q * s.length))].toFixed(0);
const long = gaps.filter((g) => g > 200).map((g) => g.toFixed(0));
console.log(`\r\nrepeats=${gaps.length} p50=${p(0.5)}ms p95=${p(0.95)}ms max=${s.at(-1).toFixed(0)}ms gaps>200ms=${long.length} ${long.join(", ")}\r`);
gaps = [];
}
The first gap of each hold (the initial repeat delay) is skipped, because hold mode already allows extra time for it.
Workaround: "voice": { "mode": "tap" } in settings.json avoids the problem, but you lose hold-to-talk.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.289 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
- macOS 26.6.2, default key-repeat settings.
- Possibly related: #46154 ("Push-to-talk broken - cuts off after 2-5 words", macOS Terminal.app). It was closed as a duplicate of #50433, which is about Linux, where no release event is ever detected. This report covers the macOS repeat-gap case, with measurements.