claude-code - 💡(How to fix) Fix native CC 2.1.117 regression: /usage via PTY drops first char after / in slash-command mode [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#51938Fetched 2026-04-23 07:40:53
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Participants
Timeline (top)
labeled ×5closed ×1

Native Claude Code (claude.exe 2.1.117 on Windows) has a regression in PTY input handling: when a wrapper script writes /usage\r to a spawned claude --dangerously-skip-permissions process, the first character after / is dropped. The u is consumed by the slash-command mode state transition, and the remaining sage\r is submitted as a plain user prompt — creating a real persisted session instead of executing the /usage slash command.

Root Cause

Native Claude Code (claude.exe 2.1.117 on Windows) has a regression in PTY input handling: when a wrapper script writes /usage\r to a spawned claude --dangerously-skip-permissions process, the first character after / is dropped. The u is consumed by the slash-command mode state transition, and the remaining sage\r is submitted as a plain user prompt — creating a real persisted session instead of executing the /usage slash command.

Fix Action

Fix / Workaround

A workaround patch with --no-session-persistence + defensive keystroke timing is being filed against the cc-analytics repo.

Code Example

const pty = require('node-pty').spawn('claude', ['--dangerously-skip-permissions'], {
  name: 'xterm-256color', cols: 120, rows: 80,
});
pty.write('\x1B');              // Esc to dismiss any pending notification
setTimeout(() => {
  pty.write('/usage\r');         // expected: execute /usage slash command
}, 500);
RAW_BUFFERClick to expand / collapse

Summary

Native Claude Code (claude.exe 2.1.117 on Windows) has a regression in PTY input handling: when a wrapper script writes /usage\r to a spawned claude --dangerously-skip-permissions process, the first character after / is dropped. The u is consumed by the slash-command mode state transition, and the remaining sage\r is submitted as a plain user prompt — creating a real persisted session instead of executing the /usage slash command.

Impact

Third-party analytics tooling that scrapes /usage TUI output via PTY spawns (e.g. cc-analytics VS Code extension) creates a phantom Claude session per scrape. Over 48 hours at a 15-minute refresh cadence, this produced 30+ phantom sessions on the affected machine, each submitting the prompt sage (the surviving chars of /usage after /u is dropped) and consuming quota for the assistant's "did you mean?" clarification.

Reproduction

Pseudocode matching the pattern used in [email protected]/tools/fetch-usage.js:

const pty = require('node-pty').spawn('claude', ['--dangerously-skip-permissions'], {
  name: 'xterm-256color', cols: 120, rows: 80,
});
pty.write('\x1B');              // Esc to dismiss any pending notification
setTimeout(() => {
  pty.write('/usage\r');         // expected: execute /usage slash command
}, 500);

Expected: /usage panel renders with quota data. Actual: sage submits as a user prompt; a new session is created and persisted to ~/.claude/projects/<slug>/<session-id>.jsonl; the assistant responds with a "did you mean?" message.

Evidence

  • ~/.claude/history.jsonl: 30 consecutive entries with display: "sage" at 15 / 30 / 45-minute intervals, each with a unique sessionId, each correlating to an actual session transcript file.
  • pastedContents: {} on every entry — confirms the text arrived via keystroke injection, not paste.
  • First assistant response in each phantom session is a clarification question about what "sage" means.

Hypothesis

Slash-command mode activation appears to race with keystroke consumption. When / arrives, the TUI transitions to slash-command-input state, but that transition is async — the next character (u) may arrive before the state machine is ready to consume it, landing in the submit-as-prompt handler. The tail (sage\r) then completes as a normal prompt submission.

Worked on npm, broke on native

This scrape pattern reportedly worked on the npm-distributed @anthropic-ai/claude-code package. The regression appears in native claude.exe 2.x — likely timing or state-machine differences between the embedded Node runtime and the bundled native binary.

Environment

  • OS: Windows 11 Pro 10.0.26200
  • claude --version: 2.1.117 (Claude Code)
  • Install path: ~/.local/bin/claude.exe (Windows native installer)
  • PTY wrapper: node-pty, xterm-256color, 120x80 grid
  • Consumer: [email protected] VS Code extension on a 900 s refresh timer

Ask

  1. Fix the input race so the first character after / isn't dropped when keystrokes arrive in a PTY faster than the slash-command state-machine can settle.
  2. Expose a non-interactive quota endpoint — e.g. claude quota --json or a stable file at ~/.claude/quota.json — so third-party analytics tooling doesn't have to scrape the TUI at all. This would close the whole class of issue.

A workaround patch with --no-session-persistence + defensive keystroke timing is being filed against the cc-analytics repo.

extent analysis

TL;DR

The most likely fix is to modify the claude.exe native binary to handle the input race condition when processing slash commands in PTY input handling.

Guidance

  • Investigate the timing differences between the embedded Node runtime and the bundled native binary to understand why the regression appears in native claude.exe 2.x.
  • Consider implementing a small delay between writing the / character and the rest of the command to ensure the state machine is ready to consume the next character.
  • Review the cc-analytics tooling to see if there are any modifications that can be made to handle the input race condition, such as adding a short delay before writing the /usage command.
  • Explore the possibility of exposing a non-interactive quota endpoint, such as claude quota --json, to eliminate the need for scraping the TUI.

Example

No code snippet is provided as the issue is related to the native binary and PTY input handling.

Notes

The issue is specific to the native claude.exe 2.x binary on Windows, and the regression is not present in the npm-distributed @anthropic-ai/claude-code package.

Recommendation

Apply a workaround patch with --no-session-persistence + defensive keystroke timing in the cc-analytics repo, while investigating a long-term fix for the input race condition in the claude.exe native binary.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix native CC 2.1.117 regression: /usage via PTY drops first char after / in slash-command mode [1 participants]