Session metadata keeps a stale worktreePath/worktreeName after the worktree directory is removed
Description
get_session (and the list_sessions entries) continue reporting a worktreePath/worktreeName for a session even after that worktree directory has been removed from disk (e.g. after the branch's PR merges and the worktree is cleaned up, either manually with git worktree remove or via the app's own cleanup). This was observed across multiple completed sessions in the same project:
- A session with a merged PR still reports
worktreePath: /path/.claude/worktrees/intelligent-wright-1c891a— directory confirmed absent on disk, branch confirmed deleted both locally and onorigin. - Same pattern for another session with a different merged PR.
- A third session (no PR, never touched the codebase — used only for scheduling a reminder via the
/scheduleskill) also still reports aworktreePathfor a directory that no longer exists.
By contrast, at least one other session in the same project (also a merged PR) correctly has no worktreePath field at all — so the metadata can get cleared, just not consistently.
Impact
Low severity — no data loss observed, since in every case the underlying git work was already safely merged (or, for the scheduling-only session, never existed). But it's misleading: reading session metadata suggests a worktree is still there to resume into, when in fact resuming would presumably need to recreate it from scratch (or silently fail if the branch is also gone).
Repro sketch
- Start a session with
EnterWorktree(or the app's normal per-task worktree flow). - Merge its PR and remove the worktree (
git worktree remove, or via the app'sclean_up_worktrees/ manual removal). - Call
get_sessionon that session later —worktreePathis still present and points at a now-nonexistent directory.
4 Comments
Update: broader scope, plus a related staleness bug
Followed up in the same project and the scope is larger than originally reported.
worktreePathstaleness affects nearly every completed session, not just 3The project's
.claude/worktrees/directory is completely empty on disk (confirmed viagit worktree listand a directory listing). At least 13 sessions in this one project still report aworktreePath/worktreeNamepointing into that empty directory:intelligent-wright-1c891a,journal-card-layout-bug-2f230c,elevenlabs-ascend-integration-28ca30,consistent-male-voice-readaloud-3f87ac,ascend-dark-light-mode-6c8c9c,association-links-notice-board-48b99b,player-icons-india-u19-e94356,wow-card-ordering-72eebc,heart-rate-hrv-screen-movement-8d8d2a,gifted-haslett-4a650a,notice-board-card-customization-87a572,state-assoc-link-saved-status-ea467b, and the one from the original report.Exactly one session in the same project (
academix-deck-ordering-0e2faf) correctly has noworktreePathfield at all — so whatever mechanism clears it does work sometimes, just not reliably/consistently.No data loss found, for what it's worth — every session in this set either has its PR already merged, or (for the two with no PR/branch at all) never actually wrote any application code (one was a discussion-only session explicitly deferred by the user, the other was pure diagnosis of an unrelated caching issue on the user's device). Filing this purely as a metadata-hygiene bug, not a data-safety one.
Related: cached
prStateinlist_sessionscan also go staleSeparately, one session's
list_sessionsentry reportsprState: "OPEN"for a PR that is actuallyMERGEDon GitHub (confirmed live viagh pr view). This looks like the same class of issue as theworktreePathstaleness above — session-list metadata that isn't being refreshed/invalidated when the underlying state changes (worktree removed, PR merged) — so it may share a root cause or fix path. Flagging both together in case that's useful context, but happy to split theprStateone into its own issue if preferred.Split the
prStatestaleness finding into its own issue: #95725If you fix this, please reference this issue (e.g. "Fixes #95723") in the PR description so it closes automatically on merge.
Further confirmation, from the app's own storage accounting
Ran the desktop app's own \
get_storage_usage\tool (Settings › Desktop app › Storage) against this same project, and it corroborates the bug independently of my manual \git worktree list\checks — and at a larger scale:\
\\json\"worktrees": {
"count": 30,
"repo_count": 1,
"bytes": 0,
"held_by_sessions_count": 30,
"held_by_sessions_bytes": 0,
"kept_ready_count": 0,
"kept_ready_bytes": 0,
"kept_dirty_count": 0,
"kept_after_archive": []
}
\
\The app believes 30 worktrees are currently "held by sessions" in this one repo — every single one reporting 0 bytes. A real worktree with a checked-out source tree is never 0 bytes. Combined with \
git worktree list\on disk showing zero worktrees for this repo (just the main checkout), this means the app's worktree-accounting is carrying 30 phantom entries, not the 13 I sampled by hand earlier in this thread — the real number (at least for this repo) is 30.None of them are in \
kept_ready\or \kept_after_archive\, so this isn't the intentional reuse-pool or archived-with-uncommitted-changes cases the tool documents — these are just stale "still held" records for worktrees that no longer exist.