# \[Bug\]: Switching thread branch to a worktree mid-turn silently kills the running Claude session · Issue \#14245 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/14245)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: backlog

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/14245)

---

### Before submitting
- [x] I searched existing issues and did not find a duplicate.
- [x] I included enough detail to reproduce or investigate the problem.

### Area
apps/web

### Steps to reproduce
1. Start a thread (Claude provider) in a repo that has extra git worktrees (created outside T3, e.g. `git worktree add ../wt-feature feature`).
2. Send a prompt that produces a long-running turn.
3. While the turn is running, open the branch picker in the composer toolbar and select `feature` (the branch that is checked out in the other worktree). The goal is just to look at its diff in the Diff panel.
4. Watch the thread.

### Expected behavior
The running turn is not killed silently. Either:
- the branch picker is disabled while the session is `starting`/`running`, or
- the user is asked to confirm and is told that the current turn will be interrupted.

### Actual behavior
- The streamed output stops. There is no prompt or warning before the switch, and nothing in the thread explains that the turn was killed by the branch change.
- The Claude process is terminated and the turn ends as `interrupted` ("Session stopped.").
- Nothing happens until the user sends another message (e.g. `.`). Then a new session is started in the new worktree and resumed from the stored resume cursor. This looks like the stream "came back", but it is a new turn, and the interrupted turn's work may be left half done.

### Code path (commit d2c9281b)
- `apps/web/src/components/BranchToolbarBranchSelector.tsx:176-194`: `setThreadBranch` calls `stopThreadSession` whenever `worktreePath !== activeWorktreePath`, without checking whether a turn is running:
  ```ts
  if (serverSession && worktreePath !== activeWorktreePath) {
    void stopThreadSession({ environmentId, input: { threadId: activeThreadId } });
  }
  ```
- `BranchToolbar.logic.ts:262-289`: the worktree path changes when the selected ref already has a worktree (`reuseExistingWorktree`) or when the default branch is selected from a worktree.
- `BranchToolbarBranchSelector.tsx:813`: the trigger is disabled only by `isInitialBranchesLoadPending || isBranchActionPending`, not by session status. `envLocked` (`ChatView.tsx:2626-2630`) locks the env/worktree mode selectors but not the branch picker, even though `BranchToolbar.tsx:553` says started server threads have their workspace pinned.
- `apps/server/src/provider/Layers/ClaudeAdapter.ts:4259-4360`: `stopSessionInternal` terminates the process and calls `completeTurn(context, "interrupted", "Session stopped.")`.
- `ProviderCommandReactor.ts:842` + `ProviderService.ts:1466-1470`: the next `thread.turn.start` starts a new session in the new cwd using the persisted resume cursor.

### Suggested fix
Disable the branch picker (or at least ref selections that change `worktreePath`) while the session is `starting`/`running`. Alternatively, show a confirmation that interrupts the turn explicitly and leaves a visible "interrupted by branch switch" marker in the thread.

### Impact
Major degradation or frequent failure. Users switch branches just to inspect a diff and lose the running turn with no feedback.

### Version or commit
0.0.43-nightly.20260929.2428 (AppImage). Code references from `main` at d2c9281b.

### Environment
Linux (Ubuntu), desktop app, Claude Code provider.

### Workaround
Do not change the branch while a turn is running, or view the other worktree's diff outside T3.

