claude-code - 💡(How to fix) Fix [BUG] isolation: "worktree" — only 1 of 7 concurrent worktrees branched from current HEAD; other 6 used origin/HEAD

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When 7 sub-agents are spawned in a single Agent tool call with isolation: "worktree" and run_in_background: true, 6 of 7 worktrees were created from origin/HEAD (a remote branch unrelated to the active local branch) instead of the current HEAD. The 7th worktree was correctly based on current HEAD — and the only observable difference for that one was that the parent Claude personally extended its state (added a file) before any other ops ran.

This is a near-duplicate of #48095 (origin/HEAD instead of HEAD) and #61264 (concurrent agents on stale commits), but adds new evidence: the bug is not deterministic across a parallel spawn batch — one worktree out of seven escaped it, suggesting a race or a code path dependent on parent activity rather than a pure default-ref bug.

Root Cause

Worth investigating because the existing similar bugs (#48095, #61264) describe a consistent wrong-base; this batch was inconsistent.

Fix Action

Workaround

Pre-flight check in each sub-agent prompt:

First, run: git rev-parse HEAD
Expected base SHA: <pass-in-from-parent>
If they don't match, STOP and report the actual SHA. Do not proceed.

Also helpful (from #48095): a PreToolUse hook on Agent that runs git remote set-head origin "$(git branch --show-current)" so origin/HEAD tracks the active branch.

Code Example

First, run: git rev-parse HEAD
Expected base SHA: <pass-in-from-parent>
If they don't match, STOP and report the actual SHA. Do not proceed.
RAW_BUFFERClick to expand / collapse

Summary

When 7 sub-agents are spawned in a single Agent tool call with isolation: "worktree" and run_in_background: true, 6 of 7 worktrees were created from origin/HEAD (a remote branch unrelated to the active local branch) instead of the current HEAD. The 7th worktree was correctly based on current HEAD — and the only observable difference for that one was that the parent Claude personally extended its state (added a file) before any other ops ran.

This is a near-duplicate of #48095 (origin/HEAD instead of HEAD) and #61264 (concurrent agents on stale commits), but adds new evidence: the bug is not deterministic across a parallel spawn batch — one worktree out of seven escaped it, suggesting a race or a code path dependent on parent activity rather than a pure default-ref bug.

Reproduction

  1. Repo with two long-lived branches (beta/5.6.x and beta/6.0.x); origin/HEADbeta/5.6.x
  2. Check out feature branch: git checkout beta/6.0.x (current HEAD = 3f34cbb0)
  3. Make a local commit on the feature branch that isn't yet pushed
  4. In a single Agent tool invocation, spawn 7 sub-agents with isolation: "worktree" and run_in_background: true
  5. Each sub-agent: git rev-parse HEAD as the first command in its worktree

Expected: all 7 print 3f34cbb0 (current HEAD). Observed: 1 prints 3f34cbb0; 6 print 4cc3b9fa — the tip of beta/5.6.x (= origin/HEAD).

The asymmetry (the novel part)

Of the 7 sub-agents, only the one whose worktree was extended by the parent Claude (the parent did a Write into that worktree shortly after spawn, before any other agents started touching their worktrees) was based on the correct HEAD. The other 6 were all based on origin/HEAD.

This could be:

  • A race in worktree base-ref resolution during concurrent spawn
  • A code path that's only exercised when the parent interacts with the worktree before the child does
  • Coincidence (n=1)

Worth investigating because the existing similar bugs (#48095, #61264) describe a consistent wrong-base; this batch was inconsistent.

Impact

Near-miss SEV2. The 6 wrong-based agents each made small, individually-correct lint-cleanup diffs — but on top of beta/5.6.x instead of beta/6.0.x. If merged via classic merge, would have regressed:

  • App version 6.0.0+468 → 5.6.5+457
  • Flutter SDK floor >=3.44.0 → >=3.35.0
  • 50+ package version pins downgraded
  • Workspace plugin face_liveness_native removed
  • flutter_localizations commented out

Caught downstream when the squash-merge chain hit a gitea update_branch 409 conflict. ~70 min of cherry-pick recovery. No regression reached the protected branch.

Environment

  • Platform: macOS (Darwin 25.5.0)
  • Claude Code: 2.1.150
  • Date: 2026-05-26

Workaround

Pre-flight check in each sub-agent prompt:

First, run: git rev-parse HEAD
Expected base SHA: <pass-in-from-parent>
If they don't match, STOP and report the actual SHA. Do not proceed.

Also helpful (from #48095): a PreToolUse hook on Agent that runs git remote set-head origin "$(git branch --show-current)" so origin/HEAD tracks the active branch.

Related

  • #48095 — isolation: "worktree" branches from origin/HEAD (same root cause)
  • #61264 — concurrent agents on stale commits (same symptom class)
  • #62309 — claude --worktree bases on origin/<default> (CLI variant)

Detailed postmortem

Full timeline, 5-whys, and recovery write-up: shared on request — happy to attach the postmortem .md if useful.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING