Repository navigation
[Bug]: Claude account switch skips running panes: only previous-account panes are candidates, and after an update none of those restarted #33551
Description
Operating system
macOS
Orca version
1.4.240 (auto-updated from 1.4.237 a few minutes before the switches below)
Details
Summary
With When you switch accounts while Claude is running set to Always restart (claudeAccountSwitchRunningSessions: "restart"), two account switches in a row restarted 1 Claude terminal pane. 16 other panes stayed on an account that had reached its weekly limit, so every prompt in them returned "You've hit your weekly limit". The status bar showed the newly selected account with free usage, so the status bar and the running sessions disagreed, and no message said that panes were skipped.
There are two separate problems:
- By design, a switch only considers panes that it can tie to the account selected immediately before the switch. A pane that runs on an earlier account is never offered, even with Always restart.
- Right after the app updated, a switch away from the panes' own account also restarted none of them, although 11 of the 16 had an idle Claude status that pointed at that account.
What happened
One local host, terminal panes only. Orca started every Claude process (no hand-started claude, no tmux).
- 16 Claude panes ran on Account A. Each
claudeprocess hasCLAUDE_CONFIG_DIR=<Orca user data>/claude-profiles/<A>/home. Orca 1.4.237 had started or resumed them one to two days earlier, several of them through its own restart-on-switch. A then reached its weekly limit. - Orca auto-updated from 1.4.237 to 1.4.240 and relaunched. The 16 panes kept running in the previous version's terminal host. The process tree shows each
claudeunder that host. New panes start in the new host. - About 5 minutes later, I signed in again to Account B and selected it. No pane restarted.
daemon.logshows no kill and no spawn in this window. - A new Claude pane started on B, in the new terminal host.
- I selected Account C. Orca restarted only the B pane from step 4 ("Restarting 1 Claude session"). The 16 panes from step 1 stayed on A. After this step, a prompt in an A pane still returned A's weekly-limit error.
Checks after step 5:
ps ewwfor each of the 16claudeprocesses:CLAUDE_CONFIG_DIRis still A's folder, whileclaude-profiles/selected-hostnames C.- In
orca worktree ps --json, 11 of the 16 panes had an idle (done) agent row. Their persisted hook status (agent-hooks/last-status.json) has atranscriptPathunder A's folder. The other 5 panes had no agent row.
Cause, as far as I can trace it (v1.4.240 source)
-
Only panes on the outgoing account are candidates.
handleRunningClaudeSessionsAfterSwitchpasses the account that was selected just before the switch asfromAccountId(claude-account-switch-sessions.ts L101, L121-L128).findMovableClaudeSessionsdrops every pane whose account is not exactlyfromAccountId(claude-session-account-move.ts L195-L198). After A → B → C, the A panes can move only on a switch away from A. This fully explains step 5. -
The pane's account is inferred from its hook status, not recorded at launch.
resolveClaudeSessionAccountIdreads the account fromproviderSession.transcriptPath(L81-L102), andlocalClaudePanesInLaneskips any pane that has noagentStatusByPaneKeyentry (L145-L148). A pane without a status cannot be moved by any switch, even when it runs on the outgoing account. The 5 panes with no agent row in step 3 are likely this case. -
Not explained: in step 3, the 11 panes that had an idle status pointing at A were also skipped. What all 16 have in common is that they ran in the previous version's terminal host, while the one pane that did restart ran in the new host. The scan logs nothing, so I could not tell which check dropped them. Candidates are the renderer's
ptyIdsByTabIdbinding after the relaunch (L134-L144),inspectRuntimeTerminalProcessagainst the old host, andisClaudeInForeground(L222-L230). -
The skip is silent. When the scan finds nothing,
handleRunningClaudeSessionsAfterSwitchreturns'show-confirmation'(L134-L136). The status-bar menu ignores that result (ClaudeSwitcherMenu.tsx L193-L200), so a status-bar switch shows no message. The Settings path shows "Running sessions keep their account", which does not say which panes were skipped or why.
Codex already handles this case: listStaleCodexPanes compares each pane's recorded launch account with the active account, so every Codex pane that is not on the active account is flagged, whatever was selected before (codex-stale-pane-accounts.ts L15-L35). Claude panes have no such record.
Expected
After a switch, every running Claude terminal pane that is not on the newly selected account is restarted with claude --resume <session id> (Always restart) or listed in the Ask dialog. This includes panes started under an earlier account or System default, panes with no hook status, and panes still in the previous version's terminal host after an update. A pane that cannot be moved is listed with the reason.
Suggested fix
- Record each Claude pane's launch account when Orca starts Claude in it, as
codex-pane-account-registrydoes for Codex. Orca already chooses the account at spawn (CLAUDE_CONFIG_DIR/ORCA_CLAUDE_INJECTED_CONFIG_DIR, and theclaudeshell function readsselected-hostat each launch). - In the switch handler, select every Claude pane whose recorded account is not the new account (a Claude version of
listStaleCodexPanes), instead ofaccountId === fromAccountId. Leave out panes that are kept on their account (feat(accounts): keep a Claude or Codex agent on its account #28684). - Do not require a live hook status. Use the recorded launch account, a foreground-process check that also works for panes in an older terminal host, and a session id from the recorded provider session or from Claude's
<CLAUDE_CONFIG_DIR>/sessions/<pid>.json. - Name the skipped panes in the toast or dialog, and log one line per skipped pane with the check that dropped it.
Steps to reproduce (problem 1)
- Add three Claude accounts A, B and C. Set the switch setting to Ask.
- Select A. Start a Claude pane P1 and send one prompt.
- Select B. In the dialog, choose Keep as is. P1 stays on A.
- Start a Claude pane P2 on B and send one prompt. Set the switch setting to Always restart.
- Select C. Only P2 restarts. P1 stays on A, and no message mentions it.
I have not reproduced problem 2 in isolation. It happened on the first switch after an auto-update, with all affected panes still in the previous version's terminal host.
Workaround
In each stuck pane, run /exit, then claude --resume <session id> in the same pane. Orca's claude shell function starts it on the selected account.
Do not use /login inside the pane. It writes the new login into the pane's account folder, so the Orca account entry that owns that folder now holds a different login. Afterwards, Orca listed two account entries with the same email.
Related
- [Bug]: Account switch restarts only some running Claude panes; panes without a managed CLAUDE_CONFIG_DIR stay on the old account #31902: same symptom. Its System-default pane is a case of problem 1, because that pane's account is
null, notfromAccountId. - [Bug]: Regression: switching Claude accounts no longer updates existing Claude Code sessions #29870: a comment from 2026-10-24 reports 6 of 9 panes left on the old account.
- Claude account switch does not reach a running session; two panes in one worktree can run on two accounts #19900, and feat(accounts): offer to restart running Claude sessions on the new account after a switch #29898, which added restart-on-switch.
- feat(accounts): keep a Claude or Codex agent on its account #28684: keep a pane on its account. The fix above should leave those panes alone.
- On 1.4.237, one switch on the same machine restarted 7 of 14 running Claude panes. This is possibly the same cause. I did not check it at code level.
Activity
AmethystLiang commentedon Oct 25, 2026
looking into it
JahyunBaek commentedon Oct 27, 2026
Windows 11 reproduction of problem 2 on 1.4.242, with Always restart set. Same shape as yours: only the pane in the new terminal host restarted.
Timeline from the process tree and file times (local time, 10-27):
claude-profiles/selected-hostrewritten).claude.exe --resumestarts under the 1.4.242 terminal host. That pane restarted.daemon-host-profiles\<id>\1.4.239\…\Orca.exe, and 1 under…\1.4.235\…\Orca.exe, whose Claude has been running since 10-23./exitandclaude --resume <id>in the same pane. The new processes still start under the 1.4.239 host.So on Windows too, a pane's terminal host seems to be what decides whether the switch reaches it.
Tauri-EPO commentedon Oct 27, 2026
One more cause for the same symptom, from a Windows host. It may help separate the cases: here the switch did restart panes from the previous terminal host, and the pane that stayed behind was skipped for a different reason.
Setup
ORCA_APP_VERSION=1.4.239.claudeAccountSwitchRunningSessions: "restart"(Always restart).run_in_backgroundwatch loop that waits for orchestration mail).What happened (one switch, 2026-10-26 17:08:18Z, account A → B)
claude-profiles/selected-hostwas rewritten to B's home at 17:08:18Z.daemon.logshows four panes closed (cause: operator_close) at 17:08:19Z and respawned within one second, each with a 56-character startup command, which fitsclaude --resume <uuid>. Three of the four were in the previous terminal host (daemon pid 65064). The other one was in the new host (pid 12012). So on this machine, panes in the previous version's host did restart.claudeprocess still hasCLAUDE_CONFIG_DIR=<userData>\claude-profiles\<A>\home35 minutes later.Why the coordinator pane stays on A
agent-hooks/last-status.jsonfor that pane, 17:43Z:The transcript shows the main agent ending turns at 17:08:03, 17:13:50, 17:19:48, 17:34:00 and 17:36:01Z. In each gap the background shell was still running, so the pane's combined state stayed
working(monitoring) from 17:02:39Z on. It never reacheddone.In v1.4.241 that blocks the restart:
foldAgentLeadStatus(src/shared/agent-lead-status-fold.tsL31-L39) maps "leaddone+ live child shell" toworking/monitoring.isClaudePaneMidTurn(src/renderer/src/lib/claude-session-account-move.tsL67-L70) treats any combined state other thandoneas mid-turn.selectReadyAccountRestartPtyIds/isAccountRestartReady(pane-account-restart-readiness.tsL6-L29) for mounted panes, andrestartUnclaimedPane(codex-detached-pane-restart.tsL79-L85) for detached ones.The transcript path is under A's folder, so
resolveClaudeSessionAccountIdreturns A, which equalsfromAccountId. The pane therefore meets the candidate rules you listed. I can't read the renderer'spendingPaneAccountRestartsfrom disk, so I can't prove that the pane was queued rather than dropped by a later check. If it was queued, the restart waits for adonestate that an agent with a permanent background watch never reaches.As far as I can see, nothing shows that a Claude restart is waiting. For Codex,
CodexRestartChipshows "Codex is using the previous account" on the pane, and the status bar counts stale sessions and has a Restart button. The Claude path queues the restart with no notice (queuePaneAccountRestartsreturns before touching any notice for'claude',terminal-restart-state.tsL56-L58). This matches the reports in #29870 that long-running coordinators are the sessions that stay behind.What would help (in addition to the fixes proposed above)
orca status --jsonor the orchestrationcheckreceipt. A coordinator could then end its watch loop at a safe point and let the queued restart run. This is related to [Feature]: Switch an existing coordinator between providers without losing conversation or orchestration state #29871.Reproduced: observed once on 2026-10-26 in normal use (evidence above); not yet re-run as a controlled repro. The steps below are how I would reproduce it.
Steps to reproduce
sleep 600withrun_in_background) and then end its turn.