agent-runner: prune .claude/worktrees/agent-* on session/branch end

Resolved 💬 1 comment Opened May 1, 2026 by brandonrdug Closed Jun 1, 2026

Summary

When the Agent tool is invoked with isolation: \"worktree\", Claude Code creates a git worktree at .claude/worktrees/agent-<id>/ and a paired worktree-agent-<id> branch. After the agent thread terminates (success, failure, or timeout), neither the worktree directory nor its branch is pruned. Disk usage grows unbounded across project sessions.

Repro

In any moderately active project (mine: ~9 days of dispatch-heavy planning waves), check:

$ ls .claude/worktrees/ | wc -l
48

$ du -sh .claude/worktrees/
11G

$ git branch | grep -c worktree-agent-
46

48 directories, 46 stale branches, 11 GB on disk — none of those agent threads are still alive. PIDs in the worktree .git/locked files are long dead. Each worktree carries a full checkout (~230 MB) plus whatever the agent built into it.

Why it bites harder than just disk

There's a related correctness hazard: the worktree-merge \"silent no-op\" pattern where a leftover worktree leaves the parent repo's HEAD on worktree-agent-* instead of main, and a subsequent git merge --no-ff <agent-branch> reports \"Already up to date\" against the wrong branch. Pruning closed-thread worktrees eagerly cuts the surface area for this.

(I run a dedicated ## Worktree discipline section in my repo's CLAUDE.md warning every session to verify pwd and git branch --show-current before any merge — but that's a workaround for the cleanup gap, not a fix.)

Proposal

When an agent thread reaches a terminal state, the runner should:

  1. git worktree unlock the agent's worktree (currently auto-locked with the runner's pid).
  2. git worktree remove --force <path> to drop the directory.
  3. git branch -D worktree-agent-<id> if the branch's commits are merged into the agent's target (or if the agent thread errored out without committing anything).
  4. If the branch carries unmerged commits AND the agent succeeded, leave it but log a one-liner so the user can rescue the work; otherwise prune.
  5. As a backstop, ship a claude doctor-style command that bulk-prunes any .claude/worktrees/agent-* whose owning pid is no longer alive.

References

  • 2026-05-01 manual cleanup of 46 stale agent worktrees (~10.93 GB reclaimed) was Wave F P8.3 of an internal hygiene plan; tracked in change_proposal 0767d626-1866-4a9d-a148-6708d0b4dc1f (private repo) under goal #18 + Pattern D \"agent worktree leak\".
  • Plan ID for the cleanup wave: fe2acff3-efc0-439b-8da5-988e628b10c7.

Happy to share the cleanup workflow we ran if helpful.

View original on GitHub ↗

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