Worktree isolation inflates spawned-shell env past ARG_MAX → E2BIG on all Bash, unrecoverable without restart

Open 💬 1 comment Opened Jul 3, 2026 by lowellbander

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 ok fails 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_MAX and see intermittent E2BIG on longer commands before it ever dispatches a worktree agent. (In the repro repo, ~60 worktrees had accumulated across sessions.)

Reproduction

  1. Open a session in a repo with many skills (~38).
  2. Dispatch a subagent with isolation: 'worktree'.
  3. 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's envp was already inflated at spawn time; removing the worktree afterward doesn't shrink the live process's environment.
  • /clear does not help (same OS process, same envp).
  • Only a full CLI restart recovers (claude --continue / claude --resume spawns 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

  1. Keep skill metadata out of the spawned shell's environment. Skill descriptions are agent-context data, not shell env; passing them via envp is what blows ARG_MAX. Move them out of the spawned process's environment entirely.
  2. 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.
  3. 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.
  4. Guard the spawn. Detect envp approaching ARG_MAX and fail loudly with a clear message + self-recovery hint, instead of an opaque E2BIG on every shell call.
  5. 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗