Triage
Confirmed on current main (d2c9281b, the commit this report cites). No duplicate issue. The nightly you are on matches that tree, so this is not fixed in a newer build.
Selecting a ref that already has a worktree is a workspace retarget, not a read-only diff view. resolveBranchSelectionTarget sets reuseExistingWorktree and points nextWorktreePath at that checkout. selectBranch then calls setThreadBranch immediately, with no checkout. setThreadBranch calls thread.session.stop whenever a session record exists and the worktree path changes. It does not look at session status and does not confirm.
The branch trigger is disabled only while refs are loading or a branch action is pending. envLocked locks the environment and local/worktree mode once the thread has messages or a non-stopped session, and the toolbar comment says a started thread’s workspace is pinned. That lock is not applied to the branch picker. envLocked there only blocks picking a worktree base before a worktree exists.
The stop itself is deliberate: the provider process is bound to the old cwd, and the Diff panel follows thread.worktreePath. What is missing is a guard. The process is killed with no prompt, and the thread only gets the generic interrupted turn. For Claude that text is Session stopped. from ClaudeAdapter.stopSessionInternal. The client stop is not Claude-specific.
The same stop also runs for any other worktree-path change, including choosing the default branch while the thread is in a secondary worktree (nextWorktreePath becomes null). Choosing a branch that is not checked out elsewhere stays in the current worktree, runs switchRef, and does not stop the session. That checkout-under-a-running-turn case is separate from this report.
After the stop, the session row remains with status stopped, so nothing resumes on its own. The next message takes the fresh startProviderSession path in ProviderCommandReactor. The cwd comes from the updated thread.worktreePath, and ProviderService.startSession fills in the persisted resume cursor. That is a new turn in the other worktree, not the interrupted turn continuing.
Stopping the process on a real workspace change should stay. The picker should not be able to do that silently while the session is starting or running: either disable selections that change worktreePath, or confirm that the turn will be interrupted.