[BUG] SGR mouse-report fragments (e.g. `;35;44M`) leak into the prompt as text when the session is busy — no focus switch or external editor
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
While a session is busy (mid-stream of a long response, a heavy re-render, or a long-running tool call), scrolling the mouse wheel appends raw text to the prompt input. No key is pressed. Typical result:
> ;35;44M
The fragment is the tail of an SGR mouse report. Claude Code enables ESC[?1000h + ESC[?1006h, so the terminal sends every wheel/click event as:
ESC [ < Cb ; Cx ; Cy M
| Field | Meaning | In ;35;44M |
|---|---|---|
| Cb | button — 64/65 = wheel up/down | consumed with the ESC[< prefix |
| Cx | column | 35 |
| Cy | row | 44 |
| M | press/scroll terminator | M |
The give-away that this is a mouse event rather than keyboard corruption: the two numbers are screen coordinates and change as the pointer moves to a different part of the window.
The risk is submitting a polluted prompt — the junk lands in the input box and is easy to miss if you're typing.
Suspected root cause
The escape-sequence parser appears to time out mid-sequence under load. The binary contains escapeCodeTimeout (the standard ink/readline knob). On seeing ESC, the parser waits a bounded window for the remainder before deciding the byte was a lone Escape. When the event loop is blocked, the mouse report arrives split across reads and the timeout fires part-way through: the prefix (ESC[<64) is consumed as one token and the residual bytes (;35;44M) fall through and are treated as ordinary printable input.
That would explain why the artifact tracks session responsiveness rather than any particular keystroke or command — lag doesn't corrupt the bytes, it desynchronizes the state machine meant to swallow them.
Relationship to existing issues
This is the same defect class as the chain below, but with a different and much more mundane trigger — ordinary scrolling while the session is busy. No external editor, no IDE, no application focus switch is involved, which is what distinguishes it from all of these:
- #42606 —
CLAUDE_CODE_NO_FLICKER=1+ Ctrl-G external editor. Shows the same raw form (^[[<51;120;17M…). Auto-closed for inactivity with no fix. - #50032 — closed as a duplicate of #42606.
- #80659 — focus switch after opening a plan in VS Code (iTerm2); chains back to #42606.
Since #42606 was closed for inactivity rather than fixed, the underlying parser behaviour appears to still be present.
Environment
- Claude Code: 2.1.220
- OS: macOS 24.6.0 (Apple Silicon)
- Terminal: Warp
- Renderer:
"tui": "fullscreen" - Mouse modes requested by the TUI:
?1000hand?1006h(?1002/?1003motion tracking are not used, which matches the observation that leaks correlate with wheel/click rather than pointer movement)
Steps to Reproduce
Intermittent and load-dependent, so this is a "make it likely" recipe rather than a deterministic one:
- Run
claudein a terminal (observed in Warp; the underlying parser behaviour is not obviously terminal-specific). - Start something that keeps the session busy for a sustained period — a long streaming response or a long-running tool call.
- While output is actively streaming, scroll the mouse wheel over the window.
- Watch the prompt input box.
Observed: fragments such as ;35;44M accumulate in the input. Coordinates vary with pointer position.
Expected
Mouse reports are consumed by the input parser and never reach the prompt buffer, regardless of how busy the event loop is.
Note on the usual workaround
CLAUDE_CODE_DISABLE_MOUSE=1 is the commonly suggested mitigation, but it isn't usable under the fullscreen renderer: per #70724 the wheel is then handed to the prompt box as history navigation rather than falling back to native terminal scroll. So for fullscreen users there is currently no good mitigation for this leak.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗