Background `claude` subagent_type auto-wraps in git worktree; `general-purpose` does not; doc says neither should
Summary
Background Agent calls with subagent_type: "claude" are wrapped in a temporary git worktree even when isolation is not set. Background Agent calls with subagent_type: "general-purpose" are not. The Agent tool documentation describes isolation: "worktree" as the explicit opt-in for worktree wrapping, with no mention of subagent-type-based defaults.
Expected
Per the tool docs: "With isolation: \"worktree\", the worktree is automatically cleaned up if the agent makes no changes; otherwise the path and branch are returned in the result."
Reading: no isolation → no worktree, regardless of subagent_type or run_in_background.
Actual
subagent_type: "claude" + run_in_background: true (no isolation set) → agent runs in .claude/worktrees/agent-<id>/ on a fresh worktree-agent-<id> branch, marked locked.
subagent_type: "general-purpose" + run_in_background: true (no isolation set) → agent runs in the main checkout.
Repro
Two identical probes, only subagent_type differs. Each runs:
1. pwd
2. git rev-parse --show-toplevel
3. git rev-parse --abbrev-ref HEAD
4. git worktree list
Probe A — subagent_type: "general-purpose", run_in_background: true
pwd: /Users/<me>/path/to/repo
show-toplevel: /Users/<me>/path/to/repo
HEAD: master
worktree list: only the main checkout (plus unrelated pre-existing entries)
→ no worktree created.
Probe B — subagent_type: "claude", run_in_background: true
pwd: /Users/<me>/path/to/repo/.claude/worktrees/agent-add6c5c1b313d3ae0
show-toplevel: /Users/<me>/path/to/repo/.claude/worktrees/agent-add6c5c1b313d3ae0
HEAD: worktree-agent-add6c5c1b313d3ae0
worktree list: main + .claude/worktrees/agent-add6c5c1b313d3ae0 [locked]
→ worktree created automatically. The completion notice did include a <worktree> block (because the probe wrote a tracked file, so the harness kept the worktree).
Why it matters
Skills that spawn claude bg agents and expect them to share the main checkout's filesystem can silently lose work:
- Skill spawns
claudebg agent (noisolationset, expects main checkout). - Agent writes deliverables to a gitignored path (
_OUTPUT_/,dist/,tmp/, etc.). - Git sees zero changes in the implicit worktree.
- Harness auto-removes the "unchanged" worktree on completion (per the documented rule).
- The completion notice arrives without a
<worktree>block (worktree already gone, no path to surface). - Deliverables are destroyed before the orchestrator can copy them out.
The orchestrator has no signal that a worktree was ever involved, so it looks like the agent simply failed to produce output.
Asks
One of:
- Doc fix — document that
subagent_type: "claude"impliesisolation: "worktree"(and any other implicit couplings). - Behavior fix — make
claudehonor the documented "explicit opt-in only" rule for worktree wrapping. - Either way — when the harness auto-removes a worktree because git sees no changes, surface a warning in the completion notice ("worktree auto-removed; if your agent wrote to gitignored paths those files are gone"). Silent destruction is the painful part.
Environment
- Claude Code on macOS (Darwin 25.4.0)
- Reproduced on a clean repo with the two probes above.
4 Comments
Fix: Background
claudesubagent_type auto-wraps in git worktreeIssue: #61951
Severity: High — silent data loss for orchestrator skills
Category: Bug fix — isolation/isolation-defaults
---
Root Cause Analysis
The Bug
When
Agent()is called withsubagent_type: "claude"andrun_in_background: true(withoutisolationset), the agent is automatically wrapped in a git worktree at.claude/worktrees/agent-<id>/on aworktree-agent-<id>branch. The same call withsubagent_type: "general-purpose"correctly runs in the main checkout.Where the Bug Lives
Based on analysis of the compiled binary and SDK types, the bug is in the background agent launch path where
subagent_type: "claude"triggers an implicit worktree creation that should only happen whenisolation: "worktree"is explicitly set.Key evidence from binary string analysis:
tengu_fork_subagent_enabled— A feature flag controlling fork/subagent behavior. Theclaudesubagent type likely takes a different code path through this fork mechanism.isForkSubagentEnabled/getForkSubagentSource— Functions that determine whether to use fork-based subagent spawning. Theclaudetype likely defaults to fork mode, which unconditionally creates a worktree.buildWorktreeNotice— Constructs the worktree notification block. Called regardless of whether the worktree was explicitly requested.readWorktreeHeadSha/getWorktreeCount/getWorktreeCountFromFs/getGitWorktreeName— Worktree lifecycle management functions.cyan_FOR_SUBAGENTS_ONLY— A marker used in subagent contexts, suggesting different initialization paths for different subagent types.The Flow (Current — Buggy)
The
isolationparameter is checked only in the general-purpose path, not in the fork/claudes type path. The fork path assumes worktree isolation is always desired.---
Proposed Fix
Fix 1: Honor
isolationparameter in fork subagent path (Behavior Fix)File: Background agent launch handler (internal, near
isForkSubagentEnabled/getForkSubagentSource)Change: Add an
isolationcheck before creating the worktree in the fork subagent path:Fix 2: Surface worktree auto-removal warning (Mitigation Fix)
File: Worktree cleanup handler (near
buildWorktreeNotice)Change: When the harness auto-removes a worktree because git sees no tracked changes, add a warning to the completion notice:
Fix 3: Documentation update
Update the Agent tool documentation to clarify:
subagent_type: "claude"withrun_in_background: truecurrently has an implicit worktree default (document as a known issue with fix timeline)claudeandgeneral-purposesubagent types with background execution---
Testing Plan
Test 1: Reproduce the bug (pre-fix)
Test 2: Explicit isolation still works
Test 3: Gitignored path deliverables warning
Test 4: Worktree cleanup verification
---
Risk Assessment
---
Estimated Effort
Total: ~3 hours
Same. It's a bummer that non-git working is not taken care of
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.