claude-code - 💡(How to fix) Fix Worktree virtual-overlay evaporation: Edit/Write operations silently target ghost files when worktree disappears mid-run

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…

When a Claude Code subagent is dispatched with isolation: "worktree", the harness occasionally reports the worktree as created while the physical worktree directory does not exist on disk. The subagent's Edit, Write, and Read tool calls then succeed against a transient sandbox overlay; cargo test / bun test / etc. run inside Bash see real files via the overlay AND pass; but at session/subagent exit the overlay evaporates and the work disappears.

Two failure modes observed:

  1. Never created. The worktree directory is absent at the very first subagent Bash. Every subsequent Edit/Write/Read hits the overlay. Tests pass green against nothing. No git commits succeed (because no worktree branch ever existed). All work is lost when the overlay evaporates.

  2. Mid-run evaporation. STEP-0 dispatch verification passes (the worktree's .git is a real gitlink); the coder commits 4 commits to git successfully; the worktree directory then vanishes mid-run (git worktree list no longer reports it; ls .claude/worktrees/agent-<id>/ returns ENOENT). The commits survive because git's object store is separate from the worktree filesystem, BUT subsequent Edits go to the overlay and evaporate.

Error Message

error to the coordinator is much better than a silent overlay.

Root Cause

  1. Never created. The worktree directory is absent at the very first subagent Bash. Every subsequent Edit/Write/Read hits the overlay. Tests pass green against nothing. No git commits succeed (because no worktree branch ever existed). All work is lost when the overlay evaporates.

Fix Action

Fix / Workaround

When a Claude Code subagent is dispatched with isolation: "worktree", the harness occasionally reports the worktree as created while the physical worktree directory does not exist on disk. The subagent's Edit, Write, and Read tool calls then succeed against a transient sandbox overlay; cargo test / bun test / etc. run inside Bash see real files via the overlay AND pass; but at session/subagent exit the overlay evaporates and the work disappears.

  1. Mid-run evaporation. STEP-0 dispatch verification passes (the worktree's .git is a real gitlink); the coder commits 4 commits to git successfully; the worktree directory then vanishes mid-run (git worktree list no longer reports it; ls .claude/worktrees/agent-<id>/ returns ENOENT). The commits survive because git's object store is separate from the worktree filesystem, BUT subsequent Edits go to the overlay and evaporate.

Dispatch a subagent with isolation: "worktree". Hit rate ~89% across ~12 dispatches in a single ~6-hour session, 2026-05-22. The harness log surface gives no warning; the agent receives no failure signal; Read of a worktree path returns the overlay content (which mirrors the in-memory state) so a self-check using only Claude Code tools cannot detect the condition.

RAW_BUFFERClick to expand / collapse

Severity: P0 (silent data loss; agents ship "green" tests against ghost files)

Summary

When a Claude Code subagent is dispatched with isolation: "worktree", the harness occasionally reports the worktree as created while the physical worktree directory does not exist on disk. The subagent's Edit, Write, and Read tool calls then succeed against a transient sandbox overlay; cargo test / bun test / etc. run inside Bash see real files via the overlay AND pass; but at session/subagent exit the overlay evaporates and the work disappears.

Two failure modes observed:

  1. Never created. The worktree directory is absent at the very first subagent Bash. Every subsequent Edit/Write/Read hits the overlay. Tests pass green against nothing. No git commits succeed (because no worktree branch ever existed). All work is lost when the overlay evaporates.

  2. Mid-run evaporation. STEP-0 dispatch verification passes (the worktree's .git is a real gitlink); the coder commits 4 commits to git successfully; the worktree directory then vanishes mid-run (git worktree list no longer reports it; ls .claude/worktrees/agent-<id>/ returns ENOENT). The commits survive because git's object store is separate from the worktree filesystem, BUT subsequent Edits go to the overlay and evaporate.

Reproduction shape

Dispatch a subagent with isolation: "worktree". Hit rate ~89% across ~12 dispatches in a single ~6-hour session, 2026-05-22. The harness log surface gives no warning; the agent receives no failure signal; Read of a worktree path returns the overlay content (which mirrors the in-memory state) so a self-check using only Claude Code tools cannot detect the condition.

A user-side detection workaround: from a Bash tool call, ls -la .claude/worktrees/agent-<id>/.git and require the output be a regular file containing gitdir: .... This is reliable because Bash ls hits the real filesystem, not the overlay. We are landing this as a PreToolUse Edit/Write hook (worktree-existence-guard.ts) but the underlying platform bug should be fixed upstream.

Witness commits / artifacts from one session

Single-session evidence trail (2026-05-22, tau project):

CommitLaneFailure mode
a6f9d9b4c3bc9e7c1 (agent id)cli.syntax_highlightNever created. 3744/0 tests passed against ghost files; merge structurally succeeded; worktree branch did not exist on disk
adc581b0bbe13428b (agent id)M1a state-snapshot cleanupMid-run evaporation after 4 commits
Lane M1btpol-manual-worktree-pivot adoptedPivot away from harness-managed path
Lane M1c, M3, M4, M5a, M5b (5 further dispatches)VariousRequired tpol-manual-worktree-pivot to /private/tmp/<lane>-<id>-wt/ for survivable work

docs/bugs/worktree-coder-virtual-overlay-evaporation.md in the tau repo (private; can share on request) documents both occurrences with full timing.

Workaround in use

Coders pivot to a manually-created worktree at /private/tmp/<lane>-<id>-wt, created BEFORE the first Edit/Write via:

git worktree add /private/tmp/<lane>-<id>-wt -b worktree-agent-<id>
ls /private/tmp/<lane>-<id>-wt/.git  # must be a regular file

This sidesteps the harness-managed .claude/worktrees/agent-<id>/ path entirely. The pivot is documented in our agent-memory as tpol-manual-worktree-pivot.

What we would like

  1. Pre-dispatch verification: the harness should refuse to spawn a worktree-isolated subagent if git worktree add fails. A clear error to the coordinator is much better than a silent overlay.
  2. No transparent overlay over absent worktree dirs: if the physical directory does not exist, Edit/Write should fail loudly rather than succeed against an in-memory layer.
  3. At minimum, surfacing: a notification event when an overlay- only write happens, so PreToolUse hooks can catch the condition without needing the workaround above.

Detection mechanism we shipped on our side

We added a PreToolUse hook on Edit / Write / MultiEdit at .claude/hooks/worktree-existence-guard.ts that resolves the target path against both worktree shapes (.claude/worktrees/agent-<id>/... and /private/tmp/<lane>-<id>-wt/...), lstat()s the worktree's .git, and denies the tool call unless .git is a regular file with a gitdir: pointer. The hook fires from a real Node process spawned by the harness, so it hits the real filesystem (not the overlay) and catches both failure modes. It has no bypass envvar; the underlying platform issue is "the harness lies about this" and a bypass would just let the next typo through. Code: https://github.com/DAddYE/tau/blob/main/.claude/hooks/worktree-existence-guard.ts (after we push the current branch; happy to mirror the source here on request).

Thanks; happy to provide more reproduction data, harness logs, or run diagnostics on request.

cc Captain (Jonathan Archer / @ddagostino).

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