[BUG] 2.1.116: stray `p` character leaks into input buffer on macOS Terminal.app startup

Resolved 💬 2 comments Opened Apr 21, 2026 by demidko Closed Apr 22, 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?

Starting claude in macOS Terminal.app (Apple's built-in) pre-populates the input prompt with a visible lowercase p:

❯ p

The p behaves as a placeholder — it's replaced (not prepended) when the user starts typing. Suggests it's rendered as ghost/hint text that should be visually distinct (dimmed/italic) but renders as regular text in Terminal.app, likely because Terminal.app ignores or fails to apply the relevant SGR attributes. Regression introduced in 2.1.116. Did not occur in 2.1.114. Does not occur in modern terminals (iTerm2, Ghostty, WezTerm, kitty — all confirmed working correctly, where the placeholder is either dimmed enough to be invisible, or not rendered at all).

What Should Happen?

The input prompt should appear empty after startup (just ), with no visible placeholder character — or if a placeholder is intentional, it should be consistently dimmed across all terminals including macOS Terminal.app. Claude Code should either avoid sending the DECRQM mode 2026 status query to terminals that don't support it (Terminal.app detectable via TERM_PROGRAM=Apple_Terminal), or handle the case where the terminal fails to consume the query cleanly without letting bytes leak into stdin.

Error Messages/Logs

No error logs — silent UX regression. Captured the TTY exchange via `script -q /tmp/claude-trace.log claude`, then `cat -vet /tmp/claude-trace.log`:

Startup sequence sent by 2.1.116 (not present in 2.1.114):


^[[>0q           # XTVERSION request
^[[?2026$p       # DECRQM mode 2026 (Synchronized Output) status query  ← culprit
^[[c             # Primary Device Attributes request


macOS Terminal.app doesn't support DECRQM mode 2026 (spec from 2022) and mishandles the query — the trailing `p` from the `$p` DECRQM terminator leaks into the stdin buffer instead of being consumed as part of the escape sequence.

Steps to Reproduce

  1. Open macOS Terminal.app (Apple's default, not iTerm2/Ghostty/etc.)
  2. Run claude (tested via native install: curl -fsSL https://claude.ai/install.sh | bash)
  3. Observe input prompt immediately after UI renders — shows ❯ p instead of
  4. Type any character — p is replaced by the typed character (not prepended), confirming placeholder behavior

Optional root-cause capture:

script -q /tmp/claude-trace.log claude
# wait for "❯ p" to appear, then type /exit + Enter
cat -vet /tmp/claude-trace.log | head -60

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.114 (Claude Code)

Claude Code Version

2.1.116 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Environment:

  • Claude Code: 2.1.116 (native install)
  • Last known working: 2.1.114
  • OS: macOS on Apple Silicon
  • Terminal: macOS Terminal.app (TERM_PROGRAM=Apple_Terminal, TERM=xterm-256color)
  • Running through Docker wrapper that passes host TERM; same behavior would be expected in native install

Workarounds:

  • Switch to iTerm2, Ghostty, WezTerm, or kitty (all confirmed working)
  • Wait ~5 seconds for auto-clear before typing
  • Backspace once before typing
  • Downgrade to 2.1.114

Suggested fixes (in order of increasing invasiveness):

  1. Terminal allowlist: only send DECRQM mode 2026 query when TERM_PROGRAM is in known-compatible set (iTerm.app, ghostty, WezTerm, kitty)
  2. XTVERSION-first feature detection: parse XTVERSION response (\x1b[>0q) before probing mode 2026 — skip if terminal ID doesn't match known-supporting set
  3. Bounded-timeout response parser: if no valid \x1b[?2026;n$y reply within ~100ms, discard any stdin bytes that correspond to the query suffix

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗