[Bug] Agent removal fails when worktree directory deleted out-of-band

Status Open
Reported on v2.1.214
Maintainer reply None cached
Activity 0 comments · opened Jul 19, 2026

Bug Description
Title:
Agents view: completed agent stuck forever with "worktree could not be removed (WorktreeRemove hook failed)" after its worktree dir is deleted out-of-band

Body:

What happens

A completed/stopped background agent in the Agents (FleetView) panel cannot be
removed with ctrl+x. It reports:

worktree could not be removed (WorktreeRemove hook failed)

and the entry stays in the list permanently.

Root cause

The agent ran in a hook-created git worktree, so its job state
(~/.claude/jobs/<id>/state.json) carries worktreeHookBased: true and a
worktreePath. At some point the worktree directory (and its git registry entry
under .git/worktrees) was removed out-of-band — e.g. manual rm, a cleanup
script, git worktree prune, or a branch-integration flow.

On ctrl+x, removal still tries to tear down the worktree at the stored path.
The path no longer exists on disk and is not a registered git worktree, so the
teardown fails and the whole delete is aborted — the entry can never leave the
list. It is a closed loop: the worktree is already gone, but the panel keeps
trying to remove it.

git worktree list and .git/worktrees/ are both empty; only the stale job
state keeps pointing at the vanished path.

Repro

  1. Start a background agent in a git repo with a WorktreeCreate hook (worktree

created under .claude/worktrees/<name>).

  1. Let it finish.
  2. Delete the worktree directory out-of-band (rm -rf, or after merging the

branch) so .git/worktrees no longer knows it.

  1. In the Agents panel, ctrl+x the agent → "worktree could not be removed

(WorktreeRemove hook failed)". It never deletes.

Expected

If the worktree path no longer exists (or is not a registered git worktree),
removal should treat teardown as already-done and delete the entry, instead of
failing hard and pinning it in the list forever.

Workaround

Set "worktreeHookBased": false in ~/.claude/jobs/<id>/state.json (or delete
the job dir). ctrl+x then removes the entry cleanly.

Env

  • Claude Code v2.1.214
  • macOS (Darwin 25.x)
  • Reproduced independently on two machines; 4 stuck agents on one, 2 on the other.

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.214
  • Feedback ID: 23ac8fa3-64e8-4533-a3ab-dd4d7e88e665

Errors

[]

View original on GitHub ↗