`bgIsolation` guard recovery path is broken: error tells agents to call `EnterWorktree`, which is a deferred tool
Summary
The bgIsolation guard refuses Edit/Write in a background session that hasn't called EnterWorktree, and the error tells the agent the recovery path:
"This background session hasn't isolated its changes yet. Call EnterWorktree first so edits land in a worktree instead of the shared checkout, then retry this edit using the worktree path."
But EnterWorktree is a deferred tool in current Claude Code (its schema is not loaded; it must be fetched via ToolSearch first). The guard message doesn't mention this. Agents that follow the instruction literally either:
- Call
EnterWorktreedirectly and getInputValidationError(tool not loaded), or - Don't connect "the worktree path" with "the cwd EnterWorktree returns," re-issue Edit on the original path, hit the guard again, and bail.
End-result: from the user's perspective, the Edit tool appears to return a mysterious internal error and subagents stall. The first error message (the actual guard) gets buried under a follow-on InputValidationError, so the user-visible symptom is just "Edit broke."
Environment
- Claude Code v2.1.150
- Windows 11 Pro 10.0.26200, PowerShell
- Subagents dispatched via the vanilla
Agenttool (noisolationparameter set) - Project has no
.claude/settings.jsonoverride forworktree.bgIsolation
Evidence from session logs
Deferred-tool list shown to background sessions (confirmed in this session's SessionStart system reminder) includes EnterWorktree:
"The following deferred tools are now available via ToolSearch. Their schemas are NOT loaded — calling them directly will fail with InputValidationError: CronCreate, CronDelete, ... EnterWorktree, ExitWorktree, ..."
Guard fire from a background session transcript under ~/.claude/projects/<project>/<session>.jsonl:
[191] tool_use Write {"file_path": "<repo>\\.mise.local.toml"}
[192] tool_result ERR: <tool_use_error>This background session hasn't isolated its changes yet.
Call EnterWorktree first so edits land in a worktree instead of the shared checkout,
then retry this edit using the worktree path. (To disable this guard for this repo,
set `"worktree": {"bgIsolation": "none"}` in .claude/settings.json.)</tool_use_error>
[194] text: "The background isolation guard won't let me write directly to your main checkout
— but this is a 4-line file, so let me just give you the command. Paste this into your
PowerShell at the repo root: ..."
Note step 194: the agent did not attempt ToolSearch + EnterWorktree. It rationalized failure and asked the user to run the command manually. This is the recovery the guard's message implicitly relies on, and it doesn't happen.
Repro
- Start a background
claudesession in a git repo (noworktree.bgIsolationoverride). - From the parent session, dispatch a subagent with
Agentand instruct it to write a small new file (noisolation: "worktree"). - Observe: the subagent's first
Edit/Writereturns the guard error, and the subagent typically either errors withInputValidationErroron a directEnterWorktreecall or gives up and tells the user to run the command themselves.
Suggested fixes (any one helps; ideally all three)
- Make the guard message reference
ToolSearch. Something like:
> "Call EnterWorktree first (load its schema via ToolSearch({query: "select:EnterWorktree"}) if not already available), then retry this edit using the path returned by EnterWorktree."
- Pre-load
EnterWorktree's schema in any session where thebgIsolationguard can fire. The agent shouldn't need a hop to reach its own documented recovery path. - Default
Agentsubagent dispatches toisolation: "worktree"when the dispatched agent hasEdit/Writein its tool allowlist, OR inherit the parent's worktree state. Today the parent session can be in a worktree but the subagent it spawns isn't, which is surprising.
Why this is worse than it looks
The user-visible symptom is "Edit returns an internal error" — the actual guard text is hidden inside the subagent's transcript and not surfaced to the parent. Users don't realize there's a guard at all; they just see flaky parallel agents. In my data this is biting across multiple sessions on the same machine. Compounding bug #59848 (bg guards firing on foreground sessions on some platforms), this will become a frequent confusion source.
Related (but distinct) issues
- #59848 — interactive sessions classified as background, causing bg-only guards to fire (different root cause; same downstream UX)
- #58507 (closed) — catch-22 when cwd is already a worktree
- #59580 —
worktree.bgIsolationsetting missing from docs - #58435 (closed) — opt-out for forced-worktree enforcement
4 Comments
1|# claude-code #62372: bgIsolation Guard Recovery Path Broken — EnterWorktree is Deferred
2|
3|## Issue Summary
4|
5|The
bgIsolationguard refusesEdit/Writein a background session that hasn't calledEnterWorktree, and the error message tells the agent to callEnterWorktreefirst. However,EnterWorktreeis a deferred tool — its schema is not loaded in background sessions and must be fetched viaToolSearchfirst. Agents that follow the guard's instruction literally either:6|1. Call
EnterWorktreedirectly →InputValidationError(tool not loaded)7|2. Don't connect "the worktree path" with "the cwd EnterWorktree returns" → hit the guard again
8|
9|End result: from the user's perspective, the
Edittool appears to return a mysterious internal error and subagents stall.10|
11|## Root Cause Analysis
12|
13|### The Deferred Tool Gap
14|Background sessions have a limited tool set.
EnterWorktreeis listed as a deferred tool in theSessionStartsystem reminder:15|> *"The following deferred tools are now available via ToolSearch. Their schemas are NOT loaded — calling them directly will fail with InputValidationError: ... EnterWorktree, ExitWorktree, ..."
16|
17|The guard's error message references
EnterWorktreeby name but does not instruct the agent to first load its schema viaToolSearch. This creates an unrecoverable state because:18|1. The agent doesn't know
EnterWorktreeneeds to be searched for first19|2. Even if it does, the agent may not connect the worktree path returned by
EnterWorktreewith the path it should use for subsequent edits20|
21|### Why This Is Worse Than It Looks
22|The user-visible symptom is "Edit returns an internal error" — the actual guard text is hidden inside the subagent's transcript. Users don't realize there's a guard at all; they just see flaky parallel agents.
23|
24|## Proposed Fix
25|
26|### Fix 1: Enrich Guard Message with ToolSearch Instructions (Quick Win)
27|
28|Modify the guard error message to include explicit
ToolSearchinstructions:29|
30|``
diff\"worktree\": {\"bgIsolation\": \"none\"}31|- "This background session hasn't isolated its changes yet. Call EnterWorktree first so edits land in a worktree instead of the shared checkout, then retry this edit using the worktree path."
32|+ "This background session hasn't isolated its changes yet. To isolate changes: (1) Call ToolSearch({query: 'select:EnterWorktree'}) to load the EnterWorktree tool, (2) Call EnterWorktree() to create a worktree and get its path, (3) Retry your edit using the worktree path returned by EnterWorktree. (To disable this guard for this repo, set
in .claude/settings.json.)"`33|
bgIsolation34|
35|### Fix 2: Pre-Load EnterWorktree Schema in bgIsolation Contexts (Proper Fix)
36|
37|When the
guard can fire in a session, pre-load theEnterWorktreeandExitWorktreetool schemas so they're immediately available without aToolSearchhop:`38|
39|
typescript`40|// In session initialization for background sessions with bgIsolation enabled
41|if (session.isBackground && config.worktree?.bgIsolation !== 'none') {
42| // Pre-load worktree tools since the bgIsolation guard references them
43| await loadToolSchemas(['EnterWorktree', 'ExitWorktree']);
44|}
45|
Agent46|
47|This ensures the recovery path mentioned in the guard message is actually executable.
48|
49|### Fix 3: Default Agent Subagent Dispatch to Worktree Isolation (Best UX)
50|
51|When dispatching an
subagent that hasEdit/Writein its tool allowlist, default toisolation: "worktree":`52|
53|
typescript`54|// In Agent tool dispatch logic
55|function dispatchAgent(params: AgentDispatchParams) {
56| const hasWriteTools = params.tools?.some(t => ['Edit', 'Write', 'MultiEdit'].includes(t));
57|
58| if (hasWriteTools && !params.isolation) {
59| // Default to worktree isolation for agents that can write files
60| params.isolation = 'worktree';
61| }
62|
63| // Also inherit parent's worktree state if already in a worktree
64| if (session.worktreePath && !params.isolation) {
65| params.isolation = 'worktree';
66| params.worktreePath = session.worktreePath;
67| }
68|
69| return createSubagent(params);
70|}
71|
`72|
73|This prevents the guard from firing in the first place by ensuring subagents that need to write files are automatically isolated.
74|
75|### Fix 4: Guard Message Should Surface to Parent Session (UX Improvement)
76|
77|The guard text is currently buried in the subagent's transcript. Surface it to the parent session:
78|
79|
typescript`80|// When bgIsolation guard fires in a subagent
81|if (guardFired && session.isSubagent) {
82| // Include guard context in the error returned to parent
83| return {
84| type: 'tool_result',
85| content: error,
86| _guardContext: {
87| type: 'bgIsolation',
88| message: guardMessage,
89| recoverySteps: ['ToolSearch(EnterWorktree)', 'EnterWorktree()', 'Retry edit with worktree path']
90| }
91| };
92|}
93|
isolation: "none"94|
95|## Implementation Priority
96|
97|1. **P1 (Important)**: Enrich guard message with ToolSearch instructions — quick fix, ~10 lines
98|2. **P1 (Important)**: Pre-load EnterWorktree schema in bgIsolation contexts — proper fix, ~50 lines
99|3. **P0 (Critical)**: Default Agent dispatch to worktree isolation — prevents the issue entirely, ~30 lines
100|4. **P2 (Enhancement)**: Surface guard context to parent session — UX improvement, ~20 lines
101|
102|## Testing Plan
103|
104|1. **Unit tests**: Verify guard message includes ToolSearch instructions
105|2. **Integration tests**: Dispatch subagent with Edit/Write tools → verify worktree isolation is default
106|3. **Regression tests**: Verify existing
andisolation: "worktree"` explicit settings still work107|4. End-to-end tests: Background session → dispatch agent → write file → verify no guard fires
108|
109|## Impact
110|
111|- User impact: HIGH — Users see "Edit broke" with no actionable error message
112|- Scope: Medium — Affects all background session + Agent tool combinations on Windows
113|- Fix complexity: LOW — Message change + pre-load logic, ~100 lines total
114|- Related issues: #59848 (bg guards firing on foreground), #58507 (closed, worktree catch-22)
115|
Solution: Fix bgIsolation Guard Recovery Path
Root Cause
The bgIsolation guard's error message tells agents to "Call EnterWorktree first" but EnterWorktree is a deferred tool — its schema isn't loaded by default and must be fetched via ToolSearch. Agents that follow the instruction literally get InputValidationError, masking the original guard message.
Fix
Two-part fix:
Why This Works
Files Changed
Addressed by a merged fix. Please reopen with a fresh repro if you still see this on a current version.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.