[BUG] Switching organization in the account menu tears down every running local Cowork/Code session mid-turn
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Switching organization from the Claude Desktop account menu (e.g. Team → Personal on the same signed-in account, no logout) unconditionally stops all local sessions — including sessions that are currently running a turn. In-flight work is discarded silently: no error is surfaced in the UI, and the killed turn simply never produces output.
This is not a logout. accountId is unchanged across the event; only orgId changes. That alone is enough to tear down every running session.
main.log shows a deliberate stop path (Org changed … reinitializing sessions → Stopping session … → running → stopping), not a crash and not a signal-based kill.
Impact
Any long-running local session is lost by flipping the org picker — something users do routinely to keep personal work off a work plan, or to work around a per-org usage limit. Because the teardown does not check session state, the cost scales with how much work was in flight. There is no warning before the switch and no error after it. In the trace below, two sessions were running and both were killed by a single switch.
Analysis
- The teardown is unconditional.
Stopping session …is issued for every session in the manager regardless of lifecycle state. Three of the transitions logged areidle → stopping; two arerunning → stopping. Nothing in the path distinguishes them. - It is keyed on
orgId, not on identity.accountIdis identical before and after (see bothInitialization succeededlines). A same-account org switch is treated as a full session-manager reinitialization. - Likely structural reason: persisted sessions live under a per-org directory (
local-agent-mode-sessions/<accountId>/<orgId>/), so the manager reinitializes wholesale whenorgIdchanges. But process lifetime does not need to follow listing scope. - UI and backend desynchronize.
getSessionMissReason … reason=not_foundfires whiletopFrameUrlstill points at/cowork/local_0da49…— the window is still showing a session the backend has already dropped. The user sees no state change; the session just goes quiet. - Round-tripping makes it worse, not better. Switching back 5 seconds later stopped all 11 sessions in the other org as well. Two switches, two full teardowns.
- No SIGTERM. Unlike #62559 there is no signal in the log — this is a clean, intentional stop call, which should make it straightforward to gate on lifecycle state.
~/.claude.backup-before-account-switch-*.jsonl(the safeguard described in #73937) is not written on this path. Whatever protection that provides does not cover the desktop org switcher.- The
claude-in-chromebridge drops at the same moment (connected=false, authenticated=false, thenBridge error: Auth service error (503)) and did not recover on its own.
What Should Happen?
An org switch should re-scope the session list without terminating session processes. Concretely, any of:
- (a) Detach the UI from local sessions on org change, leaving their processes running; re-attach when the user switches back. Sessions belonging to the non-active org simply do not appear in the sidebar.
- (b) At minimum, gate the teardown on lifecycle state: never stop a session that is in
running. Let the in-flight turn finish, then stop. - (c) Failing both, block the switch with a confirmation dialog naming the running sessions, and surface a visible error in any session that is torn down — rather than letting the turn vanish silently.
(a) is the behavior users expect, and matches what the docs promise for cloud sessions ("Work continues in the background. Close your laptop and Claude keeps going."). (b) alone would remove the data loss.
Error Messages/Logs
~/Library/Logs/Claude/main.log — timestamps local; org/account UUIDs redacted.
local_0da49… = the session running a turn. local_4069… = a second, unrelated running session.
09:23:15 Emitted tool permission request … for AskUserQuestion in session local_0da49…
09:24:16 LocalAgentModeSessions.respondToToolPermission: requestId=…, decision=once
<<< turn resumes here; session is running
09:26:30 [claude-in-chrome] ensureConnected called, connected=false, authenticated=false
09:26:30 [oauth] looking up token for orgId=<ORG_A> …
09:26:30 [warn] [claude-in-chrome] Bridge error: Auth service error (503) - retry
09:26:36 [LocalAgentModeSessionManager] Org changed from <ORG_A> to <ORG_B>, reinitializing sessions
09:26:36 [LocalSessionManager] Org changed from <ORG_A> to <ORG_B>, reinitializing sessions
09:26:36 [LocalAgentModeSessionManager] Initialization succeeded - accountId=<ACCOUNT>, orgId=<ORG_B>, existingSessions=4
09:26:36 Stopping session local_fc32…
09:26:36 [Lifecycle] Session local_fc32…: idle → stopping
09:26:36 [Lifecycle] Session local_fc32…: stopping → idle
09:26:36 Stopping session local_c54d…
09:26:36 [Lifecycle] Session local_c54d…: idle → stopping
09:26:36 [Lifecycle] Session local_c54d…: stopping → idle
09:26:36 Stopping session local_4069…
09:26:36 [Lifecycle] Session local_4069…: running → stopping <<< running session #1
09:26:36 [Lifecycle] Session local_4069…: stopping → idle
09:26:36 Stopping session local_0da49…
09:26:36 [Lifecycle] Session local_0da49…: running → stopping <<< running session #2
09:26:36 [Lifecycle] Session local_0da49…: stopping → idle
09:26:36 [FileWatching] Stopping file watcher for session local_0da49…
09:26:36 [WarmLifecycle:cowork] Destroyed
09:26:36 LocalAgentModeSessions.getSessionMissReason: sessionId=local_0da49…, reason=not_found
topFrameUrl: 'https://claude.ai/cowork/local_0da49…'
09:26:37 [warn] [RemotePluginManager] Failed to refresh/prune user-installed plugins:
identity changed during the user-plugin list drain - skipping refresh/prune this cycle
09:26:39 [warn] [replaceEnabledMcpTools] Session "local_0da49…" not found after session load; skipping
09:26:39 [warn] [replaceRemoteMcpServers] Session "local_0da49…" not found after session load; skipping (x5)
09:26:41 [LocalAgentModeSessionManager] Org changed from <ORG_B> back to <ORG_A>, reinitializing sessions
09:26:41 [Lifecycle] … idle → stopping / stopping → idle (x11 sessions in the other org)
09:26:41 [WarmLifecycle:cowork] Destroyed
09:26:42 Loaded 44 messages from transcript for session local_0da49…
09:27:56 LocalAgentModeSessions.sendMessage: sessionId=local_0da49…, messageLength=91
09:27:56 [Lifecycle] Session local_0da49…: idle → initializing
09:27:56 Starting local session local_0da49… in /home/<new-vm>
09:27:57 [Lifecycle] Session local_0da49…: initializing → running
Session transcript (~/.claude/projects/…/<uuid>.jsonl): there is a hole between
00:24:16.845Z (the tool-permission response) and 00:27:57.961Z (the next user message).
The turn that was running at 09:26:36 wrote nothing at all - no error record, no
partial output, no termination marker. The transcript cannot record its own teardown,
which is why main.log is the only place this is visible.
Steps to Reproduce
Requires one Claude account belonging to two organizations (e.g. a Team org + Personal), switchable from the account menu without logging out.
- Open Claude Desktop and start a local session (Cowork or Code
</>). - Give it work that takes more than a minute, so the session stays in
running. - While the turn is actively running, open the account menu (bottom-left avatar) and switch to the other organization.
- Observe the session stop. The UI shows no error; the running turn simply never produces output.
- Switch back to the original organization. The session is not resumed and the pending turn is gone.
- Send a new message. A fresh session process starts (new VM, new home directory). The previous turn's work is not recovered.
To confirm in the log, grep -E 'Org changed|running → stopping' ~/Library/Logs/Claude/main.log — both appear within the same second.
Reproduced in both Cowork mode and Code (</>) mode.
Claude Model
None
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.246 (session SDK); Claude Desktop app 2.1.241
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
Related issues
- #62559 — same "desktop tears down a running local session on a UI state change" failure mode, but triggered by switching session focus rather than org (
LocalSessions.stopShellPty, SIGTERM / exit 143). Closed as not planned by the stale bot with no maintainer reply. - #73937 — account switch mutating live session state; establishes that a deliberate account-switch code path touching running sessions already exists.
- #88780 — auth event interrupting an in-flight turn and discarding the running operation; same argument that auth/identity changes should be deferred to a turn boundary.
- #68625 —
WarmLifecyclereaping the embedded CLI process tree ([WarmLifecycle:cowork] Destroyedappears in this trace too).
Environment detail
- Claude Desktop (Electron) on macOS — desktop app 2.1.241, renderer 1.37937.3
- Claude Code SDK installed in the session VM: 2.1.246
- One account, two organizations (Team + Personal), switched via the account menu — no logout involved
- Affects both Cowork and Code (
</>) local sessions
The "Terminal/Shell" field above is not applicable: this is the Claude Desktop app, not a terminal. No terminal is involved in the repro.
Log excerpts have org and account UUIDs redacted and working directories of unrelated sessions omitted; nothing else is altered.