[BUG] Bash tool inlines CLAUDE_ENV_FILE into a single `bash -c` argument, so a hook env file over ~128 KiB makes every Bash call fail with E2BIG and permanently breaks the session
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?
Over a long session, every Bash tool call starts failing before bash even runs, with E2BIG. Monitor calls fail the same way, and so do the shells of every sub-agent. The session loses its shell for good. Restarting with claude --resume does not fix it.
Cause: Claude Code puts the contents of the SessionStart hook env file (CLAUDE_ENV_FILE, ~/.claude/session-env/<session-id>/sessionstart-hook-0.sh) into the single bash -c argument of every shell it starts. Linux caps any one argument at 128 KiB (MAX_ARG_STRLEN), however large ARG_MAX is. SessionStart fires again on every resume and after every compaction. So a hook that appends to CLAUDE_ENV_FILE makes the file grow without limit, and once it passes ~128 KiB every spawn fails.
In my case the codex plugin's SessionStart hook (openai/codex-plugin-cc 1.0.6) appended the same 3 export lines each time. After 136 compactions the file held hundreds of copies. That plugin bug is reported separately. The fragility is in Claude Code: any hook that appends to the file will eventually kill the shell, and the error does not name the env file.
What Should Happen?
Bash calls keep working no matter how large the hook env file gets. For example:
- Source the env file by path inside the command (
source <file>) instead of pasting its contents into the argument. - Or remove duplicate lines when merging it, and cap its size with a clear error naming the hook and the file.
- The E2BIG message names the biggest contributor (env file, shell snapshot or sandbox arguments). Tracking down the cause here took a long investigation.
- Ideally, SessionStart after a compaction does not re-append env output that is already there.
Error Messages/Logs
Could not start /bin/bash: the command line plus environment exceed the OS exec argument limit (E2BIG).
At spawn: command line 133KB across 3 args (largest single arg 133KB); environment 3.3KB across 47 vars (largest: LS_COLORS at 1.7KB).
Single-argument size across successive failures: 128.1 → 129.1 → 131.8 → 132.8 → 133.0 → 133.3 → 133.5 KB
(133.0 → 133.3 was across a quit + `claude --resume`: SessionStart appended ~0.3 KB, one block of 3 export lines)
Steps to Reproduce
- Add a SessionStart hook that appends to the env file, e.g. in ~/.claude/settings.json:
"hooks": {"SessionStart": [{"hooks": [{"type": "command",
"command": "echo \"export DEMO_VAR='$(head -c 300 /dev/zero | tr '\\0' x)'\" >> \"$CLAUDE_ENV_FILE\""}]}]}
- Start a session, then resume or compact it repeatedly. The file grows ~310 bytes per SessionStart.
(Faster: write ~130 KB of export X=... lines to ~/.claude/session-env/<session-id>/sessionstart-hook-0.sh directly, then restart and resume.)
- Once the file passes ~128 KiB, ask Claude to run any Bash command (e.g.
echo ok): it fails with E2BIG. - Quit and run
claude --resume: it still fails, because the file is re-read and grows again. - Workaround: overwrite the env file with de-duplicated content, then restart and resume. Bash works again.
(Editing the file mid-session has no effect until restart; the content is read once at session start.)
Negative controls: dangerouslyDisableSandbox: true gives the same size (the sandbox is inactive anyway: socat not installed). Deleting large scratchpad directories and a plain restart both leave the size unchanged. There are no hooks, sandbox keys or deny rules in any settings file other than the plugin's.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.281 (Claude Code)
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
I have created this github ticket on codex-plugic-cc