Subagent worktree: non-idempotent mkdir + process handle leak (Windows 11)

Resolved 💬 1 comment Opened Apr 29, 2026 by bjaxcaby Closed May 31, 2026

Environment

  • Claude Code 2.1.123
  • Windows 11 Pro (Git Bash + VS Code Claude Code extension)
  • Custom subagent definitions with isolation: worktree in frontmatter
  • Parallel spawn pattern (multiple Agent calls in a single message) and serial spawn (separate messages)

Issue 1 — Spawn-side: non-idempotent mkdir

Second and subsequent subagent spawns in a session fail with:

EEXIST: file already exists, mkdir 'C:\<path>\.claude\worktrees'

The first spawn of the session creates the parent directory .claude/worktrees. Subsequent spawns appear to call mkdir non-recursively on the same already-existing parent and abort before the agent does any work. Reproduces with both parallel spawns (multiple Agent calls in one message) and serial spawns (Agent calls across subsequent messages).

Reproduced 6× in our test run: 1 success + 5 parallel failures + 1 serial failure.

Likely fix: pass { recursive: true } to the worktree parent-dir mkdir call in the runtime, or guard with existence check.

Issue 2 — Completion-side: process handle leak

After a subagent returns its result and the parent session continues, the underlying subagent process does not exit. The worktree remains OS-locked:

git worktree remove --force fails: cannot remove a locked working tree, lock reason:
claude agent agent-<id> (pid <N>): Permission denied

Even \-f -f\ (double-force) cannot override the OS-level handle. Filesystem \rm -rf\ of the worktree path also fails with Permission denied while the pid holds open handles. Cleanup is blocked until session restart frees the handle.

This is distinct from Issue 1 — Issue 1 is at spawn time, Issue 2 is at completion / cleanup time. They occur in the same workflow but have different mechanisms.

Likely fix: ensure subagent process closes worktree handles on result-return.

Reproduction

  1. Define a custom subagent in .claude/agents/<name>.md with isolation: worktree in frontmatter
  2. Spawn 2+ instances in a single Claude Code session (parallel or serial)
  3. Issue 1: second spawn fails with EEXIST
  4. After first agent returns its result: Issue 2: worktree cannot be cleaned up via git worktree remove --force until session restart

Impact

  • Blocks parallel multi-agent patterns when agents declare isolation: worktree
  • Workaround possible for some patterns (drop isolation: worktree, write outputs to non-gated paths) but does not extend to agents that need a diff-as-PR review surface (e.g., proposing Tier 1 documentation edits)
  • Combined effect: the runtime worktree subsystem is broken on both spawn and teardown
  • Operator-facing: git worktree list accumulates ghost orphans across sessions

Workaround we applied

For our specific pattern (parallel verifiers writing reports to a non-gated path), we dropped isolation: worktree from the agent definition's frontmatter and let the verifiers write directly to the canonical output folder. Works for read-and-report patterns where worktree is cosmetic. Does not work for patterns where the diff-as-PR mechanism is load-bearing.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗