Worktree isolation inflates spawned-shell env past ARG_MAX → E2BIG on all Bash, unrecoverable without restart
Summary
After dispatching a subagent with isolation: 'worktree', every subsequent Bash tool call in the parent session fails with:
E2BIG: argument list too long, posix_spawn '/bin/zsh'
No shell can be spawned for the rest of the session — even echo ok fails identically. Non-shell tools (Read/Edit/Write/Grep) keep working because they don't spawn a shell. There is no in-session recovery; only a full CLI restart clears it.
Environment
- Claude Code v2.1.200
- macOS (Darwin),
ARG_MAX≈ 1 MB - Model: Opus 4.8
- A project with many auto-registered skills (~38 in the repo where this reproduced), each carrying a full description
- Multi-agent worktree workflow (an "EM" parent session dispatches "IC" subagents with
isolation: 'worktree')
Root cause (hypothesis)
Creating the worktree triggers auto-registration of the repo's skills a second time, scoped to the worktree path (e.g. .claude/worktrees/agent-<id>:<skill>), each carrying its full description. These skill descriptions appear to be injected into the spawned shell's environment (envp). The duplicated skill set pushes total envp size over ARG_MAX, so posix_spawn('/bin/zsh') fails before it can run anything.
Evidence:
- Bash worked fine before the worktree was created; the first failure immediately followed the worktree's skill-registration dump (a system message re-listing all skills scoped to the worktree path).
- The failure is on shell spawn (
posix_spawn '/bin/zsh') — i.e. argv/envp size — not on the command;echo okfails the same way. - Non-shell tools are unaffected, consistent with a limit hit only at process-spawn time.
- Follow-on: stale worktrees left on disk from a prior session re-register on the next session's startup, so a fresh session can begin already near
ARG_MAXand see intermittentE2BIGon longer commands before it ever dispatches a worktree agent. (In the repro repo, ~60 worktrees had accumulated across sessions.)
Reproduction
- Open a session in a repo with many skills (~38).
- Dispatch a subagent with
isolation: 'worktree'. - After the worktree registers its scoped skills, run any Bash call in the parent.
→ E2BIG: argument list too long, posix_spawn.
Accumulation variant: leave several worktrees on disk, start a fresh session, and observe intermittent E2BIG on longer commands from the start.
Impact
Total loss of shell-dependent work mid-session, with no in-session recovery:
gh(PR review, issue filing, comments, merge), git, the test suite /tsc/ lint,/code-review,/security-review— anything that spawns a shell.- For a multi-agent (EM/IC) workflow this is severe: the parent can dispatch a worktree agent and read its diff, but then can't run review gates, update GitHub, dispatch the next wave, or merge — the session strands at the review gate and a human has to intervene.
Recovery today (restart only)
- Pruning the worktree on disk (
git worktree remove <path> --force) does not restore Bash — the running process'senvpwas already inflated at spawn time; removing the worktree afterward doesn't shrink the live process's environment. /cleardoes not help (same OS process, sameenvp).- Only a full CLI restart recovers (
claude --continue/claude --resumespawns a fresh process with a clean environment). With the worktree already pruned, the fresh session also won't re-register the scoped skills.
Proposed fixes
- Keep skill metadata out of the spawned shell's environment. Skill descriptions are agent-context data, not shell env; passing them via
envpis what blowsARG_MAX. Move them out of the spawned process's environment entirely. - Don't re-register the full skill set for a worktree of the same repo. A worktree already has the repo's skills; the second, path-scoped registration is what doubles the payload.
- Prune stale worktree skill registrations on session startup so a fresh session doesn't inherit a pre-inflated env from a prior session's leftover worktrees.
- Guard the spawn. Detect
envpapproachingARG_MAXand fail loudly with a clear message + self-recovery hint, instead of an opaqueE2BIGon every shell call. - Allow an in-session env reset — a way to shrink/reset the tool environment without a full restart would turn a session-ending failure into a hiccup.
Workaround
Keeping .claude/worktrees/ pruned (removing worktrees whose branches are merged + clean) relieves the pressure, but it's mitigation, not a fix — the core issue is that skill metadata is being passed through the spawned shell's envp at all, and that a same-repo worktree re-registers its skills.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗