stablyai/orca · warning · Error
A Claude account switch is already in progress.
Error message
A Claude account switch is already in progress.
What it means
Thrown by beginClaudeAuthSwitch() when the module-level switchInProgress flag is already true. The flag is a process-wide mutex (single boolean) serializing Claude account switches; calling beginClaudeAuthSwitch() a second time before endClaudeAuthSwitch() resets it is rejected. This prevents two concurrent rotations of single-use OAuth refresh tokens.
Source
Thrown at src/main/claude-accounts/live-pty-gate.ts:90
seededUnconfirmedPtyIds.delete(ptyId)
persistence?.addClaudeLivePtySessionId(ptyId)
}
export function markClaudePtyExited(ptyId: string): void {
const hadLivePtys = liveClaudePtyIds.size > 0
liveClaudePtyIds.delete(ptyId)
seededUnconfirmedPtyIds.delete(ptyId)
persistence?.removeClaudeLivePtySessionId(ptyId)
notifyDrainedOnTransition(hadLivePtys)
}
export function hasLiveClaudePtys(): boolean {
return liveClaudePtyIds.size > 0
}
export function beginClaudeAuthSwitch(): void {
if (switchInProgress) {
throw new Error('A Claude account switch is already in progress.')
}
switchInProgress = true
}
export function endClaudeAuthSwitch(): void {
switchInProgress = false
}
export function isClaudeAuthSwitchInProgress(): boolean {
return switchInProgress
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Guard the caller with isClaudeAuthSwitchInProgress() before calling beginClaudeAuthSwitch().
- Ensure endClaudeAuthSwitch() always runs in a finally block around the switch logic so the flag can never get stuck.
- Debounce/coalesce rapid UI switch requests so only one proceeds.
- If the flag is stuck true after a crash, surface a 'switch in progress' state to the UI rather than throwing.
Example fix
// before
export function beginClaudeAuthSwitch(): void {
if (switchInProgress) {
throw new Error('A Claude account switch is already in progress.')
}
switchInProgress = true
}
// after — caller side
beginClaudeAuthSwitch()
try {
await performSwitch()
} finally {
endClaudeAuthSwitch()
} Defensive patterns
Strategy: validation
Validate before calling
if (isClaudeAuthSwitchInProgress()) {
return { status: 'already-in-progress' }
}
beginClaudeAuthSwitch() Prevention
- Always pair beginClaudeAuthSwitch with endClaudeAuthSwitch in a finally block.
- Check isClaudeAuthSwitchInProgress() before beginning.
- Debounce UI switch requests so duplicates coalesce.
- Surface 'switch in progress' state to the UI to prevent double-submit.
When it happens
Trigger: A second UI action (e.g. user double-clicks 'switch account', or an automation fires selectAccount concurrently) invokes beginClaudeAuthSwitch while a prior switch is still running. endClaudeAuthSwitch was not called because the first switch threw before its finally block.
Common situations: Double-click on a switch-account button. Concurrent IPC handlers triggering selection. A prior switch crashed and left switchInProgress stuck true (missing endClaudeAuthSwitch in a finally).
Related errors
- Terminal input is locked by another client.
- Codex reset attempt journal identity changed
- mobile relay upgrade host was removed
- Host not found
- mobile relay pairing recovery pending
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/829d31f2cd4b2bde.
Report an issue: GitHub.