anthropics / anthropics/claude-code
[BUG] Windows: Bash tool commands are silently truncated at ~8,181 chars of the bash.exe -c argument, and every \\ is halved
- Vorherrschende Sprache
- Python
- Sterne
- 145k
- Forks
- 23.1k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
### What happens
On Windows the Bash tool passes the whole command to Git's `bash.exe` as a single `-c` argument:
```
bash.exe -c "source && export TEMP=... && eval '' && pwd -P >| "
```
(That's `/proc/$$/cmdline` from inside the tool's shell.) Two things go wrong at the node → bash.exe argv hand-off, and I can reproduce both with plain Node spawning `bash.exe` directly, so this isn't the wrapper — it's the transport:
1. **The `-c` argument is cut off between 8,181 and 8,190 characters.** Bash then reports `unexpected EOF while looking for matching `'`` (or `here-document ... delimited by end-of-file`) and nothing runs. Because the wrapper rewrites every `'` as `'"'"'`, the line number in the error is just the last `'` in the user's text before the cut, which sends you hunting for a quoting bug that doesn't exist. libuv only refuses at 32,767 (`ENAMETOOLONG`), so anything between ~7.5K and 32K chars fails this way with no diagnostic pointing at length.
2. **Every doubled backslash arrives halved.** `A\\B` reaches bash as `A\B`, `G\\\\H` as `G\\H` — inside a quoted heredoc too. libuv quotes the argument by MS-CRT rules (a backslash is only doubled before a `"`), while the MSYS2 runtime parses `\\` inside a double-quoted argument as an escape. Writing the same script to a file and running the file is byte-exact.
A census of my own transcripts (7,815 Bash commands, 37 sessions) shows 0 truncation failures under 8K expanded chars and 25 of 29 at 9K and above; plus a handful of `SyntaxError: unterminated string literal` in Python heredocs that were the halving.
### Repro (no Claude Code needed)
```js
// node repro.js -- Node 24.19, Git for Windows 2.55.0.windows.3
const { spawnSync } = require('node:child_process');
const bash = 'C:\\Program Files\\Git\\usr\\bin\\bash.exe'; // same result with bin\bash.exe
for (const n of [8100, 8180, 8190, 8200, 9000]) {
const script = 'echo START; : ' + 'a'.repeat(n - 24) + '; echo END';
const r = spawnSync(bash, ['-c', script], { encoding: 'utf8' });
console.log(script.length, JSON.stringify(r.stdout.trim()), r.stderr.trim().slice(0, 60));
}
// 8100 "START\nEND"
// 8180 "START\nEND"
// 8190 "START" <- tail gone, no error
// 8200 "START"
// 9000 "START"
const r = spawnSync(bash, ['-c', "printf '%s\\n' 'A\\\\B G\\\\\\\\H' | /usr/bin/od -c"], { encoding: 'utf8' });
console.log(r.stdout); // A \ B G \ \ H <- sent A\\B G\\\\H
```
Through the Bash tool the ceiling for the user's command is lower — roughly 7,000 chars / 100 lines — because the wrapper text and the `'"'"'` expansion share the same 8K budget.
### Expected
Either the command runs, or the tool says it's too long. Today it does neither: the command is silently truncated and bash reports a quoting error inside the body.
### Suggested fix
On Windows, hand the script to bash via stdin or a temp file (`bash ` / `bash -s < file`) instead of as a `-c` argument — that removes both the length cap and the backslash re-interpretation. Failing that, refuse commands whose assembled `-c` argument exceeds ~8,100 chars with a clear message.
### Environment
- Claude Code 2.1.263, Windows 11 Enterprise 10.0.26200
- Node v24.19.0 (nvm4w), Git for Windows 2.55.0.windows.3 (`bin\bash.exe` wrapper → `usr\bin\bash.exe`, MSYS2 bash 5.3.15)
- Same behaviour with `CLAUDE_CODE_GIT_BASH_PATH` unset (default discovery)
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Start with the plain Node spawnSync repro against Git's bash.exe and compare the 8,180/8,190-character cases plus the backslash sample. Then trace the Bash tool's Windows command transport that builds the bash.exe -c argument. Done means commands are passed without truncation or backslash changes, or overly long commands receive a clear error.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- bash, git, javascript, node.js
- Bereich
- cli, operating-systems, tooling
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 52/100