[BUG] Worktree cleanup is unsafe on Windows — 'git worktree remove --force' destroys NTFS junction targets, so vendor-created worktrees accumulate with no safe way to reclaim them (130 GB, ~30% of a week's usage spent trying)
Summary
Claude Code creates isolated worktrees automatically and never reclaims them (see #84027 — the harness dirties each one via .claude/settings.local.json, which permanently disqualifies it from auto-cleanup).
The compounding problem is that the obvious remediation is unsafe on Windows. git worktree remove --force recurses into NTFS directory junctions and deletes the junction target's contents. So a user who accumulates worktrees cannot simply remove them — and the vendor's own cleanup path uses the same mechanism.
Net result on this machine: 136 registered worktrees, ~130 GB, and after a full night of remediation work, zero bytes reclaimed — because every removal now requires individually proving it is safe.
The data-loss mechanism, verified by controlled comparison
On 2026-07-08 an emergency disk reclaim ran git worktree remove --force on worktrees containing NTFS junctions that pointed back into the main tree's data directories. The junction targets were destroyed — files gone, directory shells left behind.
The mechanism was then isolated empirically. Removing a directory containing a junction as a child:
| Method | Junction target |
|---|---|
| Remove-Item (pwsh 7.5.8) | preserved |
| Remove-Item (Windows PowerShell 5.1) | preserved |
| rm -rf (git-bash) | preserved |
| shutil.rmtree (Python) | preserved |
| git worktree remove --force | TARGET DESTROYED |
Every general-purpose deletion tool treats the junction as an opaque link. Only git's worktree-removal path recurses through it. This is specific to that code path, not to recursive deletion in general.
Why this makes the accumulation unfixable rather than merely annoying
- Worktrees are created automatically, per isolated agent and per workflow step.
- They are never auto-removed (#84027).
- The natural cleanup command can silently destroy data outside the worktree on any Windows repo that uses junctions — a common pattern for keeping large data directories out of a checkout.
- Therefore cleanup must be done with custom, junction-aware machinery, with per-worktree classification and per-removal safety proof.
My own scheduled TTL census reports 0 of 112 worktrees retirable under its current rules, because the guards it inherited after the incident refuse everything. Creation is automatic and unconditional; removal requires bespoke tooling and manual adjudication.
Cost
This is the part that does not appear in #84027, and it is the reason I am filing separately.
- ~30% of one week's usage has gone to diagnosing and attempting to clean up worktree/file accumulation that the tool created.
- A full night of dedicated remediation produced zero reclaimed bytes — the effort went into building junction-safe removal machinery and proving it correct, because no safe path shipped with the product.
- The investigation itself required three independent review passes before the cause was found, two of which were structurally blind for an unrelated reason (see #84161).
- 136 worktrees and ~130 GB remain as of filing.
I am not asking for compensation. I am reporting that the remediation burden for an automatic, unbounded, vendor-created artifact is currently borne entirely by the user, using metered capacity, with no safe first-party tool to do it.
Related reports from other users
At least nine issues describe this accumulation, and several describe the other side of it — cleanup destroying real work when it does fire (e.g. #46444, #48927, #57767 for Windows lock failures during cleanup). #55435 (48 worktrees / 11 GB in 9 days) was closed not planned.
Taken together those reports say: it accumulates without bound, and cleaning it up is dangerous. Both halves need an answer.
What would resolve this
- Fix #84027 so worktrees that finish clean are actually collected — this stops the accumulation at the source.
- Make first-party worktree removal junction-safe on Windows: detect reparse points and unlink them (
rmdiron the link) before invoking git's removal, or refuse and report rather than recursing. Any internal cleanup sweep needs the same treatment. - Ship a supported reclaim command — something a user can run to safely retire finished worktrees, rather than each user writing and validating their own.
Environment
- Claude Code 2.1.222 (accumulation observed across 2.1.212 → 2.1.222)
- Windows 11, NTFS, git 2.47.1
- 136 registered worktrees, ~130 GB, ~945,000 files at time of filing