[BUG] Mouse movement injects SGR escape sequences into chat input in browser-based terminals (Lightning Studio)

Status Open
Reported on v2.1.168
Maintainer reply ✓ Yes — bcherny
Activity 7 comments · opened Jun 8, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Description

When using Claude Code inside a browser-based terminal (Lightning Studio, which uses xterm.js over WebSocket), moving the mouse over the Claude Code TUI injects raw SGR mouse tracking escape sequences directly into the chat input field as literal text.

Steps to Reproduce

  1. Open Claude Code v2.1.168 inside a Lightning Studio terminal (browser-based, xterm.js over WebSocket)
  2. Start a conversation
  3. Move the mouse cursor over the Claude Code chat window

Actual Behavior

The chat input is flooded with raw mouse tracking escape sequences, e.g.:

150;7M149;7M143;7M135;8M119;9M105;10M99;11M95;11M93;11M92;11M91;11M92;11M96;9M98;8M99;7M99;8M97;10M95;12M94;14M93;16M94;17M94...

These appear to be SGR mouse protocol coordinates (\e[<Cb;Cx;CyM) with the escape prefix stripped, injected into stdin as literal text rather than being consumed by the TUI.

Expected Behavior

Mouse movement should not produce any visible output in the chat input field.

Environment

| Field | Value |
|-------|-------|
| Claude Code version | 2.1.168 |
| Terminal | Lightning Studio (browser-based, xterm.js over WebSocket) |
| OS | Linux (cloud-hosted Studio) |

Does NOT reproduce in

  • VS Code integrated terminal (native Electron)
  • Cursor integrated terminal (native Electron)

Persists across

  • Terminal tab refreshes
  • New Studio instances

Notes

The issue is specific to browser-based WebSocket terminals. The hypothesis is that Claude Code's TUI enables a mouse tracking mode that the Studio's xterm.js implementation advertises support for, but then forwards the raw escape bytes to stdin as literal text rather than consuming them — which works fine in native Electron terminals (VS Code/Cursor) but breaks in browser-proxied ones.

Possible workaround to investigate: detecting TERM_PROGRAM / terminal capabilities before enabling mouse tracking, or providing a --no-mouse flag.

View original on GitHub ↗

7 Comments

stazcp · 2 months ago

<img width="1347" height="479" alt="Image" src="https://github.com/user-attachments/assets/d6e418aa-bb44-4c90-88d7-73e81be98401" />

github-actions[bot] · 2 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/30644
  2. https://github.com/anthropics/claude-code/issues/49017
  3. https://github.com/anthropics/claude-code/issues/58653

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

stazcp · 2 months ago

duplicate was closed but issue not resolved

orbitrod · 2 months ago

I am having this same problem in Ghostty on Mac.

jonathanhhb · 2 months ago

Same symptom, different environment — running Claude Code v2.1.181 inside GNU screen on Linux/SSH reproduces this identically.

Environment

  • Claude Code: 2.1.181
  • OS: RHEL 8 (Linux 4.18), bash, SSH session
  • Multiplexer: GNU screen ($STY set, $TMUX empty)
  • $TERM: screen.xterm-256color
  • ncurses: 6.1.20180224

Repro

  1. SSH to a Linux host.
  2. Start GNU screen: screen
  3. Run claude.
  4. Move the mouse over the terminal window → continuous stream of <row>;<col>M text injected into the prompt:

168;38M169;38M170;38M171;37M172;37M173;37M174;37M...

Outside screen (bare SSH shell), no leak.

CLAUDE_CODE_DISABLE_MOUSE=1 from #66808 is a viable workaround here — confirms the root cause is mouse-tracking init firing in environments that don't consume the reports.

+1 on the suggestion to gate mouse tracking on terminal capability. For GNU screen specifically, $STY set or $TERM starting with screen are reliable signals to skip mouse init.

davidszp · 1 month ago

Happens to me after each wake-up from suspend (laptop, local machine) when using a remote terminal connection to a VM running Claude code inside tmux.

bcherny collaborator · 10 days ago

Confirmed / reproduced on 2.1.233 (Linux).

Claude Code enables SGR any-motion mouse tracking so terminals report mouse events. Reports that arrive in one piece are consumed correctly — but when the terminal splits a report across writes (as browser/WebSocket terminals like xterm.js-based Lightning Studio do under latency), and the two halves arrive more than ~50–100 ms apart, the escape prefix (\e[<35;) gets flushed and the remainder (150;7M) is inserted into the chat input as literal text — exactly the flood you saw. Native Electron terminals deliver reports whole, which is why VS Code/Cursor are unaffected.

This is a bug in how mouse reports fragmented across input reads are handled; we're looking at buffering the partial sequence instead of flushing it.

In the meantime, the workaround you asked about already exists: set CLAUDE_CODE_DISABLE_MOUSE=1 to turn off mouse tracking entirely (documented on the settings page at https://code.claude.com/docs/en/settings — mouse motion then produces no reports at all; keyboard scrolling still works).

🤖 Generated with Claude Code