Agent({ isolation: "worktree" }) inherits last-checked-out branch instead of pinning to a base ref — causes cross-agent contamination on parallel spawn
When multiple Agent({ isolation: "worktree" }) calls are made in rapid succession (parallel fan-out from a parent session), the harness creates each worktree at .claude/worktrees/agent-<id>/ via git worktree add <path> without -b or an explicit ref. The new worktree therefore inherits whatever branch was last checked out in the underlying repository state. When agent N+1 spawns moments after agent N has switched its worktree to its own auto-named branch, agent N+1's worktree initializes on agent N's branch — not the parent session's branch.
Reproduce
- Start a session on a branch other than
main(e.g.feature-branch). - In one message, spawn three
Agent({ isolation: "worktree" })calls with file-disjoint tasks. - Inspect each agent's first response —
gitBranchfield in the transcript header.
Observed (6-agent parallel fan-out)
T+0s agent A cwd=worktrees/agent-A... gitBranch=feature-branch
T+37s agent B cwd=worktrees/agent-B... gitBranch=feature-branch
T+54s agent C cwd=worktrees/agent-C... gitBranch=feature-branch
T+65s agent D cwd=worktrees/agent-D... gitBranch=worktree-agent-C ← inherited C's auto-named branch
T+72s agent E cwd=worktrees/agent-E... gitBranch=worktree-agent-C ← same
T+82s agent F cwd=worktrees/agent-F... gitBranch=worktree-agent-C ← same
Agents D/E/F each detected this and hard-reset to the correct base, adding 30–60s of recovery time per agent and creating real risk of accidentally merging unrelated work back to the parent branch.
There's also a related symptom: the parent session's tree can drift if it does its own git checkout while parallel worktree agents are running — git checkout feature-branch can silently fail because a still-running agent's worktree holds the ref, and the parent session ends up on the wrong branch without noticing. Defensive: check the exit code, or surface the failure to the user.
Suggested fix
When creating the worktree, use git worktree add -B agent-<id> <path> <baseRef> where <baseRef> is the parent session's HEAD (or, ideally, an explicit baseRef argument accepted on the Agent call). The -B flag creates a new named branch at the worktree fully isolated from whatever HEAD currently points to, which also obviates the workarounds agents have to perform.
Workarounds for users in the meantime
- Stagger spawns past branch-switch (~60s gap between agents), or
- Have the parent session re-
git checkout <baseRef>immediately before eachAgentcall, or - Pre-create the per-agent branch yourself and pass the worktree path explicitly.
Other notes
- The harness's worktree directories appear to accumulate as
lockedeven after the spawning Claude process exits (git worktree list -vshowed 40+ stale locked worktrees from prior sessions). Some prune-on-exit / liveness-check behavior would also help.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗