{"record":{"id":"8262de4eb7af9177","repo":"stablyai/orca","slug":"a-claude-account-switch-is-in-progress-try-again","errorCode":null,"errorMessage":"A Claude account switch is in progress. Try again after it finishes.","messagePattern":"A Claude account switch is in progress\\. Try again after it finishes\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ipc/pty.ts","lineNumber":4491,"sourceCode":"        await assertFolderWorkspacePtyPathUsable(args.worktreeId)\n      }\n      const cwd = resolvePtySpawnStartupCwd(args.worktreeId, args.cwd)\n      const provider = getProvider(args.connectionId)\n      const freshSpawnRecovery = preAdoptedStablePane\n        ? undefined\n        : recoverFreshSpawnProviderRouting(\n            provider,\n            args.connectionId,\n            args.sessionId,\n            args.isNewSession\n          )\n      if (freshSpawnRecovery) {\n        await freshSpawnRecovery\n      }\n      const isClaudeLaunch =\n        !preAdoptedStablePane && !args.connectionId && isClaudeLaunchCommand(args.command)\n      if (isClaudeLaunch && isClaudeAuthSwitchInProgress()) {\n        throw new Error('A Claude account switch is in progress. Try again after it finishes.')\n      }\n      // Why: runtime-created terminals carry no renderer-computed projectRuntime; resolve from worktreeId to honor the project's Windows runtime.\n      const terminalRuntimeOptions =\n        process.platform === 'win32' && !args.connectionId\n          ? resolveLocalWindowsTerminalRuntimeOptions({\n              requestedShellOverride: undefined,\n              settings: getSettings?.(),\n              projectRuntime: resolveLocalProjectRuntimeForWorktreeId(store, args.worktreeId),\n              fallbackHostShell: process.env.COMSPEC || 'powershell.exe'\n            })\n          : { shellOverride: undefined, terminalWindowsWslDistro: null }\n      const daemonShellOverride = terminalRuntimeOptions.shellOverride\n      const isDaemonHostSpawn =\n        !args.connectionId &&\n        !(provider instanceof LocalPtyProvider) &&\n        !routesFreshSpawnsToLocalProvider(provider)\n      const callerRequestedSessionId = args.sessionId?.trim()\n      const requestedSessionId =","sourceCodeStart":4473,"sourceCodeEnd":4509,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/pty.ts#L4473-L4509","documentation":"First of four identical-message guards. Thrown at the preflight of one pty spawn controller when isClaudeLaunchCommand(args.command) is true AND the module-level switchInProgress flag in live-pty-gate.ts is true. switchInProgress is set by beginClaudeAuthSwitch and cleared by endClaudeAuthSwitch — it marks a Claude account switch mid-flight during which spawning a new Claude CLI would inherit half-rotated credentials.","triggerScenarios":"Launching a Claude command (detected by isClaudeLaunchCommand) while a managed Claude account switch is running. isClaudeLaunch requires no preAdoptedStablePane and no connectionId (i.e. a fresh local Claude pane), then checks isClaudeAuthSwitchInProgress().","commonSituations":"User clicked 'switch Claude account' and immediately opened a new Claude terminal; programmatic switch (settings sync, account picker) racing a workspace-restore spawn; switch that crashed without calling endClaudeAuthSwitch leaving the flag stuck true.","solutions":["Retry the spawn after the switch completes — the message is literal.","If the error persists, the switch flag may be stuck: ensure beginClaudeAuthSwitch/endClaudeAuthSwitch are wrapped so endClaudeAuthSwitch always runs (try/finally).","Gate the UI: disable the 'new Claude terminal' action while isClaudeAuthSwitchInProgress() returns true.","For a stuck flag, restart the main process to reset the module-level boolean."],"exampleFix":"// before\nbeginClaudeAuthSwitch()\nawait doSwitch()\nendClaudeAuthSwitch()\n\n// after — guarantee the flag clears even on throw\nbeginClaudeAuthSwitch()\ntry {\n  await doSwitch()\n} finally {\n  endClaudeAuthSwitch()\n}","handlingStrategy":"retry","validationCode":"import { isClaudeAuthSwitchInProgress } from '../claude-accounts/live-pty-gate'\n\nfunction canSpawnClaudeNow(): boolean {\n  return !isClaudeAuthSwitchInProgress()\n}","typeGuard":"function isClaudeAuthSwitchInProgressError(err: unknown): boolean {\n  return err instanceof Error && err.message === 'A Claude account switch is in progress. Try again after it finishes.'\n}","tryCatchPattern":"try {\n  await spawnPty(args)\n} catch (err) {\n  if (isClaudeAuthSwitchInProgressError(err)) {\n    // surface as 'please retry' — do not count as a hard failure\n    return { kind: 'retry' }\n  }\n  throw err\n}","preventionTips":["In the UI, disable 'new Claude terminal' while isClaudeAuthSwitchInProgress() is true.","Wrap every beginClaudeAuthSwitch/endClaudeAuthSwitch pair in try/finally so the flag cannot stick.","Subscribe to a 'switch-finished' signal so the UI re-enables spawn promptly."],"tags":["claude","auth","account-switch","managed-account","launch-guard"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}