Back to Insights
21 Jun 20264 min readAI & LLMs

Your Agent Fleet's Worktrees Are a Minefield. Here's How to See It.

The standard way to run coding agents in parallel is one git worktree each: every agent gets its own directory and branch, they don't trip over each other, and you fan out five, ten, twenty of them. It works great — right up until cleanup. A worktree is also a place work goes to die quietly: an agent edits files but never commits, or commits to a branch nobody ever pushed, and then a git worktree remove (or an auto-cleanup) takes the directory and the work with it. anthropics/claude-code#46444 is the worst version we've seen documented: worktree auto-cleanup silently deleted ~10 days of uncommitted work, ~300 files, because they were never committed.

The fix isn't a better undo — it's seeing the risk before you pull the trigger. So we wrote a 90-line tool that answers one question across every worktree in a repo: would I lose work if this got removed right now?

What "at risk" actually means

There are exactly two states where removing a worktree destroys work:

  1. Uncommitted changes. Files an agent edited but never git add-ed are ordinary files. Delete the directory and they're gone — fsck, reflog, none of it helps, because nothing was ever written to the object store.
  2. Commits that are on no remote. A commit is durable, but only as far as it has been pushed. A branch that lives only in a worktree — committed but never pushed — loses those commits if the branch and worktree are deleted together. (You can sometimes still fsck them back for two weeks; you'd rather not bet a launch on it.)

Everything else — committed and pushed — is safe. The whole tool is just: for each worktree, check those two things.

The tool

worktree-doctor parses git worktree list --porcelain, then for each worktree checks git status --porcelain (dirty?) and git rev-list --count HEAD --not --remotes (commits on no remote?). Run it from anywhere in the repo:

$ worktree-doctor
worktree-doctor — 5 worktrees, 4 at risk

  ● /repo                 [main]          uncommitted changes · 8 commit(s) on no remote
  ● /repo-wt-blog         [blog/xyz]      uncommitted changes · 10 commit(s) on no remote
  ○ /repo-wt-osdash       [osdash/abc]    safe
  ● /repo-wt-research     [research/def]  uncommitted changes
  ● /repo-wt-social       [team/social]   uncommitted changes

commit or push the flagged worktrees before any cleanup —
`git -C <path> stash` or a throwaway WIP commit is enough.

That's real output from one of our machines — four of five worktrees were holding work that a cleanup would have eaten. The key column is the flags: uncommitted changes and N commit(s) on no remote are the two failure modes spelled out per worktree. git rev-list HEAD --not --remotes is the load-bearing trick: it counts commits reachable from this worktree's HEAD but present on no remote-tracking branch — exactly the commits that vanish if the branch is deleted, whether or not an upstream was ever set.

It exits non-zero when anything is at risk, so it drops straight into a pre-cleanup check:

worktree-doctor --quiet && some-cleanup-script   # only proceeds if everything is safe

--quiet prints just the at-risk worktrees, so a clean fleet is silent and a risky one is loud.

Why this beats "just be careful"

Three things make worktree loss insidious in a fleet, and visibility kills all three:

  • It's invisible by default. git status only shows you the worktree you're standing in. With a dozen agents in a dozen directories, you have no single view of which ones are dirty — until worktree-doctor gives you one.
  • The dangerous state looks identical to the safe one. A worktree with 10 unpushed commits and one with everything pushed are the same directory from the outside. The only way to tell is to ask git, per worktree, which is exactly the loop the tool runs for you.
  • Cleanup is often automated. The whole point of a fleet is that you don't babysit it. If a script or a tool prunes worktrees, the human is never in the loop to notice the dirty one — unless the prune is gated on a check that fails loudly.

The honest caveats

It's a point-in-time snapshot, not a daemon — it tells you the risk now, so run it before any cleanup, not once a week. "On no remote" is measured against your remote-tracking refs, so git fetch first if they might be stale (the tool works on what git currently knows). And it deliberately treats the main worktree like any other: your primary checkout can be dirty and unpushed too, and it should show up red when it is.

The real lesson

Running agents in worktrees is the right pattern — but it quietly multiplies the number of places uncommitted work can hide, and the failure is total and silent when it happens. The cheap insurance is a single command that turns "I hope nothing's dirty" into a list. Pair it with the discipline from the recovery post — make agents commit early and often — and the two together keep an entire fleet on the recoverable side of the line: commit removes failure mode one, push removes failure mode two, and worktree-doctor tells you when you've missed either.

We build and run autonomous agent fleets on Claude Code in production. If you're scaling past a handful of parallel agents, talk to us.


Get the tool → worktree-doctor in agent-ops — open source (MIT), a single dependency-free script, part of our toolkit for running coding agents in production.

AI agentsgit worktreefleetsafety

Found this useful?