Terminal capability probe leaks XTVERSION/DA1 replies to the screen at startup (ghostty)

Status Open
Reported on v2.1.263
Maintainer reply None cached
Activity 0 comments · opened Sep 9, 2026

Symptom

On every startup, Claude Code prints the terminal's own capability-query replies above the UI:

^[P>|ghostty 1.3.1-arch2^[\^[[?62;22;52c

These are Ghostty's answers to XTVERSION (ESC [ > 0 q) and DA1 (ESC [ c). They are echoed by the tty line discipline rather than consumed by Claude Code's parser.

Environment

  • Claude Code 2.1.263
  • Ghostty 1.3.1-arch2, TERM=xterm-ghostty, COLORTERM=truecolor, TERM_PROGRAM=ghostty
  • Arch Linux, kernel 7.1.9
  • No tmux/screen, no SSH — local terminal

Reproduction

script -q -c claude /tmp/cc.log   # start, then /exit
cat -v /tmp/cc.log | head -c 400

Byte trace

Offsets are into the cat -v output of the recording:

130  ESC[?2004h ESC[?2031h ESC[?1004h ESC[<u ESC[>5u   setup
218  ESC[>4m ESC[<u ESC[?1004l ESC[?2031l ESC[?2004l   teardown -> cooked mode, echo on
234  ESC[>0q ESC[c                                     probe sent in the gap
249  ESC P >|ghostty 1.3.1-arch2 ESC \                 reply, echoed by line discipline
271  ESC[?62;22;52c                                    reply, echoed
284  ESC[?2004h ESC[?2031h ESC[?1004h ESC[<u ESC[>5u   setup again
330  ESC[?1049h                                        alternate screen entered
7361 ESC[>0q ESC[c                                     second probe, in raw mode - consumed correctly

Claude Code sets the terminal up, tears that setup back down, and writes the capability probe inside the resulting gap while the tty is in cooked mode with echo on. The second probe at 7361 is handled correctly, so the parser itself is fine — only the pre-raw-mode probe leaks.

Ruled out

  • Hooks — all SessionStart hooks emit zero bytes when run under a pty; reproduces with hooks removed.
  • Plugins — reproduces with enabledPlugins empty.
  • Fullscreen renderer / tui setting — reproduces under CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1, where the leak occurs at offset 234 and ESC[?1049h is never sent at all.
  • User settings generally — reproduces with an empty {} project settings file, and with --setting-sources project and no settings file present.

Startups that are gated behind a dialog (first-run onboarding, or the folder-trust prompt) do not leak: there the probe happens after raw mode is established and the replies are consumed normally. That appears to be the only difference between a leaking and a non-leaking start.

Suggested fix

Send the capability probe only while raw mode is active, or drain its replies before restoring cooked mode.

View original on GitHub ↗