[BUG] 2.1.116: stray `p` character leaks into input buffer on macOS Terminal.app startup
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
- Open macOS Terminal.app (Apple's default, not iTerm2/Ghostty/etc.)
- Run
claude(tested via native install:curl -fsSL https://claude.ai/install.sh | bash) - Observe input prompt immediately after UI renders — shows
❯ pinstead of❯ - Type any character —
pis 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):
- Terminal allowlist: only send DECRQM mode 2026 query when
TERM_PROGRAMis in known-compatible set (iTerm.app,ghostty,WezTerm,kitty) - XTVERSION-first feature detection: parse XTVERSION response (
\x1b[>0q) before probing mode 2026 — skip if terminal ID doesn't match known-supporting set - Bounded-timeout response parser: if no valid
\x1b[?2026;n$yreply within ~100ms, discard any stdin bytes that correspond to the query suffix
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗