Skip to content

fix: closing one worktree closes every repo's same-numbered worktree#1015

Open
SmolSmolStar wants to merge 1 commit into
web3dev1337:mainfrom
SmolSmolStar:fix/close-session-worktree-collision
Open

fix: closing one worktree closes every repo's same-numbered worktree#1015
SmolSmolStar wants to merge 1 commit into
web3dev1337:mainfrom
SmolSmolStar:fix/close-session-worktree-collision

Conversation

@SmolSmolStar

Copy link
Copy Markdown
Contributor

Summary

In a mixed-repo workspace, closing a single worktree's terminal (the close-process × button) can close every other repo's worktree that shares the same number. Reproduced in the wild: clicking close on sandbox/work1 also closed agent-workspace/work1, USDUC/work1, and Cat-Code-Academy/work1, leaving only Test-game/work4 (the one worktree on a different number).

Root cause

SessionManager.getSessionGroupIds builds its close-list from two keys:

const keys = [composedKey, parsedWorktreeId].filter(Boolean);

composedKey is repo-scoped (sandbox-work1, correct), but parsedWorktreeId is the bare worktree number (work1). parseWorktreeKey only treats <repo>-work<N> as repo-scoped, so a bare work1 lookup in getSessionIdsForWorktree matches every repo's work1 in the workspace.

The existing tests only covered cross-workspace scoping (already handled by the workspace filter), so this same-workspace / different-repo collision slipped through. It's the same class of hazard the repo's own docs call out for remove-worktree (bare worktree ids nuke all repos).

Fix

Only ever key on repo-scoped identifiers:

  • the composed ${repositoryName}-${worktreeId} key, and
  • the session id's own repo-scoped prefix (e.g. sandbox-work1).

Never the bare worktree number.

Test plan

  • Adds a regression test that seeds several repos sharing work1 (plus one work4) in a single workspace and asserts getSessionGroupIds('sandbox-work1-claude') returns only sandbox's own sessions.
  • Verified the test fails on the old code (returns 4 extra sessions) and passes with the fix.
  • Full sessionManager.closeSession suite green (9/9), node --check clean.

🤖 Generated with Claude Code

… worktree

In a mixed-repo workspace, closing a single worktree's terminal (the close-process
button) could close every OTHER repo's worktree that shared the same number — e.g.
clicking close on sandbox/work1 also closed agent-workspace/work1, USDUC/work1 and
Cat-Code-Academy/work1, leaving only the one repo on a different number (work4).

Root cause: SessionManager.getSessionGroupIds looked up the group by two keys —
the repo-scoped `${repo}-${worktree}` AND the bare worktree number (`work1`). The
bare number is not repo-scoped (parseWorktreeKey only treats `<repo>-work<N>` as
scoped), so getSessionIdsForWorktree matched every repo's work1 in the workspace.
The existing tests only covered cross-WORKSPACE scoping (handled by the workspace
filter), so the same-workspace/different-repo collision slipped through.

Fix: only ever key on repo-scoped identifiers — the composed `${repo}-${worktree}`
key and the session id's own repo-scoped prefix (e.g. `sandbox-work1`). Never the
bare worktree number.

Adds a regression test seeding several repos that share `work1` (plus one `work4`)
in one workspace and asserting getSessionGroupIds('sandbox-work1-claude') returns
only sandbox's own sessions. Verified it fails on the old code (returns 4 extra
sessions) and passes with the fix; full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant