[BUG] Desktop WorktreePool GC still force-removes idle worktrees after #96162; --force deleted git-ignored data (days of paid model output)
What's wrong?
Related to #96162 (closed as completed 2026-09-24 12:41 UTC). This happened about five hours after that closure, and the cleaner is still active on the current build.
The Claude desktop app's background worktree GC ([WorktreePool] untracked-dir GC → reapUntrackedWorktreeDir) ran git worktree remove --force on an idle worktree under <repo>/.claude/worktrees/. Because of --force, git deleted the worktree's git-ignored files: a .local/ folder holding SQLite databases and JSONL outputs, and roughly 2.9 GB of generated images excluded by a .gitignore. It then failed partway with Directory not empty, leaving a half-emptied folder with its worktree registration gone. Nothing went to the Trash, there was no prompt or notice, and no user action or Claude session requested it.
The worktree looked "clean" to the GC because git status does not report ignored files, but the ignored files were the only copy of about three days of paid model output: ~30,000 generated asset descriptions, ~2,200 generated images (Gemini on Vertex AI, Claude on Bedrock), suggestion libraries and a search index. Recorded third-party API spend on the lost outputs was roughly US$215–300. Only ~3% of the images and almost none of the text could be recovered (images from Claude transcripts where the model had viewed them).
Log (from ~/Library/Logs/Claude/main1.log, paths shortened)
2026-09-22 14:05:01 [info] Stopping session local_<id> ... settling as stopped (exited)
2026-09-22 13:11:36 [info] [WorktreePool] untracked-dir GC kept <repo>/.claude/worktrees/<lane> (recently-active)
2026-09-23 13:34:16 [info] [WorktreePool] untracked-dir GC kept <repo>/.claude/worktrees/<lane> (recently-active)
2026-09-24 13:42:06 [error] Git command failed: git -c core.longpaths=true worktree remove --force <repo>/.claude/worktrees/<lane> { code: 255, stderr: "error: failed to delete '<repo>/.claude/worktrees/<lane>': Directory not empty\n" }
2026-09-24 13:42:06 [warn] [reapUntrackedWorktreeDir] git worktree remove refused <repo>/.claude/worktrees/<lane> (kept): error: failed to delete ...: Directory not empty
2026-09-25 13:45:33 [info] [WorktreePool] untracked-dir GC kept <repo>/.claude/worktrees/<lane> (not-a-worktree)
Earlier, the same GC removed another worktree outright:
2026-09-20 04:40:43 [info] [reapUntrackedWorktreeDir] Removed untracked worktree dir <repo>/.claude/worktrees/<other> (repo <repo>)
It is still running every 30 minutes today (desktop 2.9939.4, Claude Code 2.1.281):
2026-09-29 11:08:45 [info] [WorktreePool] untracked-dir GC: 4 untracked dir(s), 0 past min age, 0 removed
App version at the time of the deletion: 2.7032.0 (from the updater line in the same log). macOS.
What should happen?
- Never run
git worktree remove --forcefrom an automatic cleaner. Without--force, git refuses to remove a worktree with untracked or modified files; ignored files should also count as data (checkgit status --ignoredorgit clean -ndXbefore removing). - Only reap worktrees the app itself created and still owns, as #96162 asked.
- Move removed folders to the Trash, and show a notice listing what was removed.
- Provide a setting to turn automatic worktree cleanup off. I could not find one in the app's settings.
- If removal fails partway, don't leave the worktree de-registered with its contents half deleted.
Steps to reproduce (as observed)
- Create a worktree under
<repo>/.claude/worktrees/<name>and run a desktop session in it. - Write outputs to a git-ignored folder in that worktree (e.g.
.local/), commit everything tracked sogit statusis clean. - Stop the session and leave the worktree idle for about two days.
- The GC removes it with
--force; the ignored outputs are gone.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗