[Bug] Worktree isolation pin shared across parallel subagents causes cross-agent command execution
Bug Description
Title: Worktree isolation pin is shared across parallel subagents and drifts between tool calls
Environment
Claude Code CLI, macOS (darwin 25.5.0), single interactive session spawning
parallel general-purpose subagents via the Agent tool. Each subagent ran the
project's /issue skill, which creates its own git worktree under
.claude/worktrees/<name>. Repo: a Next.js app, git worktrees off one shared
checkout. Observed across ~14 subagents over one session.
Summary
The worktree-isolation "pin" (the state deciding which worktree a session's
shell and git operations belong to) appears to be shared process-wide rather
than per-agent. With several subagents active it reassigns constantly —
sometimes between two consecutive tool calls in the same agent — so a command
issued by agent A can execute inside agent B's worktree.
Some tools fail closed when this happens (safe). Others do not (unsafe), and
that asymmetry is the actual bug.
Fails closed (correct)
- Write / Edit with absolute paths: rejected with "This session is isolated in
the worktree <X>, but ..." — nothing is written anywhere.
- Compound bash commands: rejected as "too complex to verify that it stays
inside the worktree".
git -C <abs path> <cmd>: rejected as "redirects git to the shared checkout
via -C".
Does NOT fail closed (the bug)
- Bare
gitcommands run in whatever worktree the pin currently holds. - Bash writes via relative paths (
cat > relative/path, heredocs) land in
whatever worktree the pin currently holds.
bun run lint/typecheck/testsilently run in another worktree.
Concrete incidents in one session
git add -A && git commitintended for a feature branch committed onto
main in the SHARED checkout instead (commit 72f913d).
git commitfrom one agent executed in another agent's worktree. It aborted
only because nothing happened to be staged there — with staged work it would
have committed a teammate's changes under the wrong message and branch.
- A heredoc write landed in another agent's worktree (an unrelated source
file), breaking that agent's typecheck. Caught and reverted manually.
git stash -u+popexecuted in a different agent's worktree — one holding
four uncommitted files. The stash stack is shared across worktrees, so this
can silently move another session's work.
- An agent reported "lint clean" that had actually run in a different
worktree. It masked a real violation in its own tree.
- I (the parent session) ran
git reset --hard origin/mainintending it for
the shared checkout; the pin put it in a subagent's worktree and dropped two
commits from its branch. Recovered from reflog, but uncommitted work would
have been unrecoverable.
Why the obvious workarounds don't work
EnterWorktreeis not sticky: it sets cwd correctly, but the pin drifts back
on a later call, sometimes the very next one. The only pattern that held was
EnterWorktree immediately followed by exactly ONE plain git command, re-issued
before every single command.
git -C <abs>is the documented-safe form and is refused as a "redirect".- Self-guarding shapes like
test "$(git rev-parse --show-toplevel)" = "$EXPECTED" && git commit ...
are refused as "too complex to verify" — which is unfortunate, because that
shape would make this whole class of bug fail closed.
- The parent session is affected too: its pin was repeatedly reassigned into
subagents' worktrees, and cd <shared checkout> && git ... is refused, so it
could not reliably operate on its own repo root.
Impact
Silent cross-agent corruption is possible: commits on the wrong branch, writes
into the wrong tree, destructive commands hitting the wrong worktree, and green
quality gates that ran somewhere else. No work was ultimately lost in this
session, but only because agents cross-checked each other and re-verified
diffs before committing.
Expected
The isolation pin should be per-agent, not shared. Failing that, the fail-closed
guard should cover bare git, relative-path bash writes, and script runners —
or git -C <own worktree> should be explicitly allowed as the escape hatch,
since it is the natural safe form and is currently blocked.
Environment Info
- Platform: darwin
- Terminal: ghostty
- Version: 2.1.240
- Feedback ID: afb40c0b-afdc-475b-bdb2-68be5a0cfbf6
Errors
[]This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗