Agent({ isolation: "worktree" }) inherits last-checked-out branch instead of pinning to a base ref — causes cross-agent contamination on parallel spawn

Resolved 💬 3 comments Opened May 18, 2026 by Diverjim84 Closed May 18, 2026

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

  1. Start a session on a branch other than main (e.g. feature-branch).
  2. In one message, spawn three Agent({ isolation: "worktree" }) calls with file-disjoint tasks.
  3. Inspect each agent's first response — gitBranch field 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 each Agent call, 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 locked even after the spawning Claude process exits (git worktree list -v showed 40+ stale locked worktrees from prior sessions). Some prune-on-exit / liveness-check behavior would also help.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗