Windows: Bash tool silently truncates the wrapped command at 8,186 chars, so commands don't run, run partly, or dump the environment
Environment: Claude Code 2.1.281 (desktop app 2.9939.2), Windows 11, Git for Windows 2.55.0.windows.3 (msys-2.0.dll 3.6.9).
What happens: The Bash tool sends one bash -c string: source <snapshot> && export TEMP=... TMP=... && <session-env script>\n: && shopt -u extglob ... && eval '<command>' && pwd -P >| .... When bash is started from a non-MSYS process, the MSYS2 runtime silently truncates any argument longer than 8,186 characters. This is its command-line globbing (MSYS=noglob removes the cap but breaks quoting). Nothing checks the length, so:
- long commands fail with
unexpected EOF while looking for matching '(about 40 times in my transcripts since August); - a heredoc can run truncated (
here-document delimited by end-of-file); - a cut in the middle of the session-env script ran nothing and returned exit 0;
- in one session the cut landed right after
export. A bareexportprinted every exported variable (declare -x ...), including API keys and a database URL, into the transcript. Every later Bash call in that session did the same.
Aggravating bug: ~/.claude/session-env/<session>/sessionstart-hook-N.sh is never reset when SessionStart hooks re-run on resume/compact. Hooks that append (e.g. the openai-codex plugin) grow it without limit: 31 identical copies after 30 compactions, which pushed the wrapper past the limit.
Repro: From Node, spawn('C:\\Program Files\\Git\\bin\\bash.exe', ['-c', 'echo ${#BASH_EXECUTION_STRING}; : ' + 'x'.repeat(9000)]) prints 8186.
Suggested fixes: pass the script through stdin or a temp file instead of argv on Windows; or check ${#BASH_EXECUTION_STRING} against the sent length and refuse to run on a mismatch; truncate the SessionStart env file before re-running SessionStart hooks.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗