[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)

Status Open
Reported on v2.1.289
Maintainer reply None cached
Activity 0 comments · opened Oct 5, 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?

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

  1. Enable /voice in hold mode (the default) on macOS.
  2. Run 2–3 other busy Claude Code sessions so the machine is under load.
  3. Hold space and talk for 20–30 s.
  4. 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.

View original on GitHub ↗