claude-code - 💡(How to fix) Fix isolation: "worktree" does not actually isolate subagent file writes [1 comments, 2 participants]

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…
GitHub stats
anthropics/claude-code#56137Fetched 2026-05-05 05:57:15
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Timeline (top)
labeled ×4commented ×1

When the Agent tool is called with isolation: "worktree", the subagent's initial working directory is set to the new worktree, but Edit/Write tool calls still accept absolute paths. In practice subagents repeatedly hand back absolute paths that point to the parent checkout instead of the worktree, then commit those changes via Bash. Result: changes intended for the worktree branch land on whatever branch the parent has checked out (typically main), defeating the entire point of the isolation flag.

Error Message

  1. Optional, more aggressive. Refuse, with a clear error, any

Root Cause

We dispatch parallel subagents for audit/fix sweeps over a large repo. The expected workflow is "each subagent works in its own worktree, the parent merges the worktree branches when they're done." What actually happens, repeatedly, is:

  • Subagent edits files at absolute paths under the parent checkout.
  • Subagent runs git add && git commit from inside the worktree (cwd is correct), but because the staged blobs were never written to the worktree's working tree, only its index changes; the bulk of the work stays in the parent's working tree, dirtied.
  • Or the subagent cds back to the worktree and re-edits, leaving duplicate commits in two trees.
  • Or the subagent commits directly to the parent's main and never touches the worktree at all.

Two consecutive parallel rounds in our project hit this. Concrete cases:

  • Round 2 Group F: all three fixes (F1, F2, F3) committed to main.
  • Round 2 Group D: D2/D3/D4 committed to main; one accidentally bundled Group E's in-flight WIP from main into the same commit.
  • Round 2 Group C: C1 committed once to main, then again to its worktree branch, leaving an orphaned duplicate commit in history.
  • Round 1: care-review fix, admin/tenant fix, Estate CTAs fix, permissions matrix fix all committed to main.

Each round cost 30+ minutes of merge-conflict resolution, manual stash juggling, and post-hoc commit attribution. Conflicts arose in seed.ts and load-history.ts because subagents' WIP in main collided with the same subagents' final commits in the worktree branch.

Fix Action

Fix / Workaround

We dispatch parallel subagents for audit/fix sweeps over a large repo. The expected workflow is "each subagent works in its own worktree, the parent merges the worktree branches when they're done." What actually happens, repeatedly, is:

  1. Dispatch a subagent with isolation: "worktree" and a non-trivial task that requires editing several existing files.
  2. Observe (in the parent session, or in git status afterwards) that the subagent's Edit/Write file_path arguments are absolute paths under the parent checkout, not the worktree.
  3. Observe that the parent's working tree is dirty after the subagent completes, with the same files the subagent claimed to edit.

Workaround (option B in our local task)

RAW_BUFFERClick to expand / collapse

Upstream issue draft (Claude Code, option A)

This is the body for the issue filed against anthropics/claude-code per task 42's acceptance criteria. Kept in the repo so the wording is versioned and the team can see what we asked for.


Title: isolation: "worktree" does not actually isolate subagent file writes

Repo: anthropics/claude-code

Labels (suggested): bug, subagents, worktrees

Summary

When the Agent tool is called with isolation: "worktree", the subagent's initial working directory is set to the new worktree, but Edit/Write tool calls still accept absolute paths. In practice subagents repeatedly hand back absolute paths that point to the parent checkout instead of the worktree, then commit those changes via Bash. Result: changes intended for the worktree branch land on whatever branch the parent has checked out (typically main), defeating the entire point of the isolation flag.

Why this matters

We dispatch parallel subagents for audit/fix sweeps over a large repo. The expected workflow is "each subagent works in its own worktree, the parent merges the worktree branches when they're done." What actually happens, repeatedly, is:

  • Subagent edits files at absolute paths under the parent checkout.
  • Subagent runs git add && git commit from inside the worktree (cwd is correct), but because the staged blobs were never written to the worktree's working tree, only its index changes; the bulk of the work stays in the parent's working tree, dirtied.
  • Or the subagent cds back to the worktree and re-edits, leaving duplicate commits in two trees.
  • Or the subagent commits directly to the parent's main and never touches the worktree at all.

Two consecutive parallel rounds in our project hit this. Concrete cases:

  • Round 2 Group F: all three fixes (F1, F2, F3) committed to main.
  • Round 2 Group D: D2/D3/D4 committed to main; one accidentally bundled Group E's in-flight WIP from main into the same commit.
  • Round 2 Group C: C1 committed once to main, then again to its worktree branch, leaving an orphaned duplicate commit in history.
  • Round 1: care-review fix, admin/tenant fix, Estate CTAs fix, permissions matrix fix all committed to main.

Each round cost 30+ minutes of merge-conflict resolution, manual stash juggling, and post-hoc commit attribution. Conflicts arose in seed.ts and load-history.ts because subagents' WIP in main collided with the same subagents' final commits in the worktree branch.

Repro

  1. Dispatch a subagent with isolation: "worktree" and a non-trivial task that requires editing several existing files.
  2. Observe (in the parent session, or in git status afterwards) that the subagent's Edit/Write file_path arguments are absolute paths under the parent checkout, not the worktree.
  3. Observe that the parent's working tree is dirty after the subagent completes, with the same files the subagent claimed to edit.

The failure mode does not require any deliberate action by the subagent. It is the natural consequence of subagents using absolute paths that they remember from earlier in the conversation (or that the parent prompt named) without re-anchoring to the worktree.

Proposed fix (option A in our local task)

Have the runtime enforce the isolation invariant for subagents whose isolation is "worktree":

  1. Path rewriting. For every Edit/Write/MultiEdit/NotebookEdit call, if file_path is absolute and starts with the parent checkout's prefix, rewrite it to the corresponding path inside the worktree before executing.
  2. Bash anchoring. For every Bash invocation, force cd <worktree> as the first command (or run the bash with cwd set, ignoring any in-prompt cd to outside the worktree).
  3. Optional, more aggressive. Refuse, with a clear error, any Edit/Write whose path resolves outside the worktree even after rewriting (e.g. .. traversal). Do the same for Bash commands that try to cd or git -C to a parent path.

(1) and (2) alone fix the common case. (3) catches deliberate or accidental escape attempts.

Workaround (option B in our local task)

For anyone hitting this today: a PreToolUse hook on Bash|Write|Edit|MultiEdit|NotebookEdit that compares the cwd to a worktree-marker prefix and refuses tool calls whose targets resolve outside the worktree works as a stopgap. We've shipped one in our project at .claude/hooks/worktree-guard.sh, plus a small preamble helper scripts/agent-preamble.ts that prepends a "verify pwd before every git command" rule to the subagent prompt. The hook makes the failure mode loud (the subagent sees a structured deny and re-issues the call with the right path) instead of silent. We'd rather not own this code; the runtime is the right place for the fix.

Environment

  • Claude Code subagent dispatch via the Agent tool, isolation: "worktree".
  • Linux, bash, git 2.4x.
  • Project: TypeScript / Next.js multi-tenant app, ~50 source files per parallel sweep.

extent analysis

TL;DR

Enforce the isolation invariant for subagents by rewriting absolute paths to worktree paths and anchoring Bash invocations to the worktree.

Guidance

  • Implement path rewriting for Edit/Write/MultiEdit/NotebookEdit calls to replace absolute paths with worktree paths.
  • Anchor Bash invocations to the worktree using cd <worktree> or setting the cwd option.
  • Consider refusing Edit/Write calls with paths that resolve outside the worktree after rewriting.
  • Use a PreToolUse hook as a temporary workaround to compare the cwd to a worktree-marker prefix and refuse tool calls outside the worktree.

Example

// Example path rewriting function
function rewritePath(filePath: string, worktreePath: string, parentCheckoutPath: string) {
  if (filePath.startsWith(parentCheckoutPath)) {
    return filePath.replace(parentCheckoutPath, worktreePath);
  }
  return filePath;
}

Notes

The proposed fix requires changes to the runtime to enforce the isolation invariant. The workaround using a PreToolUse hook can be used as a temporary solution.

Recommendation

Apply the proposed fix (option A) to enforce the isolation invariant for subagents, as it provides a more comprehensive solution to the issue.

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

claude-code - 💡(How to fix) Fix isolation: "worktree" does not actually isolate subagent file writes [1 comments, 2 participants]