Background session: Workflow subagent with isolation:"worktree" is blocked from Write/Edit into its own worktree
Summary
In a background session, the bg write-isolation guard blocks the Write/Edit tools for a subagent that was spawned with isolation: "worktree", even though that subagent is writing to a path inside its own worktree (.claude/worktrees/<id>/…). The guard appears to gate solely on whether the parent bg session called EnterWorktree, and does not recognize the subagent's own isolation: "worktree". The subagent is forced to fall back to writing files via Bash heredocs.
Environment
- Claude Code 2.1.159
- macOS (Darwin), zsh
- Session launched as a background job
- Code changes performed by a subagent spawned via the Workflow tool with
agent(prompt, { isolation: "worktree" })
What happened
A background (parent) session dispatched a multi-phase Workflow. The parent does no file writes itself — it only orchestrates. One phase spawns a subagent with isolation: "worktree" to implement code changes and open a PR. The Workflow harness created a real git worktree for it:
<repo>/.claude/worktrees/<wt-id> <sha> [worktree-<wt-id>]
Inside that worktree, the subagent called Write/Edit on files within the worktree, e.g.:
<repo>/.claude/worktrees/<wt-id>/src/<file>
Every Write/Edit attempt (3/3) returned:
<tool_use_error>This subagent's parent bg session hasn't isolated yet, so writes to the shared checkout are blocked. Re-spawn this agent with isolation: "worktree", or have the parent call EnterWorktree before spawning. (To disable this guard for this repo, set "worktree": {"bgIsolation": "none"} in .claude/settings.json.)</tool_use_error>
Why this is a bug
Two internal contradictions in that single error message:
- The block premise is false. It says "writes to the shared checkout are blocked," but the target path is inside
.claude/worktrees/<wt-id>/…— the subagent's own isolated worktree, not the shared checkout. - The suggested remedy was already in effect. It says "Re-spawn this agent with
isolation: "worktree"" — but the agent was spawned that way (the worktree above is proof, and the resulting PR was pushed from it).
So a correctly-isolated subagent is told to do the thing it already did, and is blocked from writing into the very worktree the isolation created for it.
Expected
A subagent spawned with isolation: "worktree" should be allowed to Write/Edit files inside its own worktree, regardless of whether the parent bg session has called EnterWorktree. The parent intentionally stays un-isolated — it only orchestrates, and delegates isolation to the child. At minimum, a write whose target path is within the calling agent's own worktree should pass the guard.
Likely root cause
The bg write guard checks "has the parent bg session isolated (via EnterWorktree)?" and does not account for a Workflow-spawned subagent's own isolation: "worktree" — the Workflow isolation option creates/pins a worktree but apparently doesn't register the agent as "isolated" in the way the guard recognizes — nor does it allow a write whose target is already inside .claude/worktrees/<id>/.
Workaround
The subagent fell back to writing files via Bash (heredocs / python), which the guard permits for writes inside the worktree. It works but defeats the Write/Edit tooling, and an agent that doesn't think to fall back would simply fail. (Setting "worktree": {"bgIsolation": "none"} also disables the guard, but that gives up the protection entirely rather than fixing the recognition gap.)
Suggested fix
- Make the guard treat a write as allowed when the calling subagent has
isolation: "worktree", and/or when the target path is within the calling agent's own worktree (.claude/worktrees/<id>/…) — independent of the parent session'sEnterWorktreestate. - And/or fix the message: don't recommend
isolation: "worktree"when it is already in effect, and don't describe an in-worktree path as "the shared checkout."
---
Possibly related (docs, same area): #63315 — "[DOCS] Background session docs omit worktree-isolation behavior for spawned subagents".