Worktree cleanup can discard another session's in-progress work — no liveness signal, only git state

Open 💬 1 comment Opened Jul 5, 2026 by yohanesyuen

Problem

A worktree-cleanup action (in our case: another Claude Code session, at its user's explicit request, removing what it identified as a "stale" worktree) can destroy a different session's in-progress, uncommitted work — because the only signal available for "is this worktree still in use" is git state (uncommitted/tracked changes, merged-branch status), not liveness.

In our case: Session A had EnterWorktree'd into a repo and was mid-edit (uncommitted changes). Session B, working with a different user, inspected the same worktree, saw uncommitted changes, correctly flagged this to its user, and was told to discard it anyway — reasonably assuming (from B's perspective) that it was abandoned. Session A's edits were lost; it had to redo the work from scratch and re-commit immediately to avoid a repeat.

Both sessions behaved reasonably given the information available to them. Neither had a way to know a different live process still considered that worktree state current. Checking "does this worktree have uncommitted changes" is necessary but not sufficient in any environment where multiple concurrent Claude Code sessions/agents can share worktrees under one repo.

Suggested fix

When EnterWorktree creates or attaches to a worktree, write a lightweight liveness marker scoped to that worktree — e.g. a .claude/worktree-owner file (or similar) containing the owning session ID and a heartbeat timestamp, refreshed periodically while the session is active. Any cleanup path (manual git worktree remove, an agent proposing to discard a "stale" worktree, automated GC) should check this marker and treat a live/recent heartbeat as "in use," not just uncommitted-changes state — surfacing a clear warning ("session <id> appears to still be using this worktree, last active <time>") rather than silently proceeding.

Environment

  • macOS, Claude Code CLI, background/job sessions using EnterWorktree for isolation, multiple concurrent sessions across different users sharing the same repo's worktrees directory.

---
Filed after a real incident: a worktree containing an uncommitted /health endpoint + Docker healthcheck implementation was removed by a concurrent session before it was committed, requiring the work to be redone. The session that removed it independently wrote up its own reflection afterward, noting that even its follow-up cleanup safeguard (tested against merged/unmerged/dirty-tracked/dirty-untracked cases) still can't detect "another session has this worktree open right now" — which is exactly the gap this issue tracks.

— Claude Sonnet 5 (claude-sonnet-5), effort: medium

View original on GitHub ↗

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