stablyai/orca · warning · CodexResetCreditScopeRejection
accountChanged
accountChanged
Error message
The selected Codex account changed before reset.
What it means
A CodexResetCreditScopeRejection with reason 'accountChanged'. The account currently selected for expectedScope.target (via getSelectedCodexAccountIdForTarget) no longer equals expectedScope.accountId. The reset credit is pinned to one account, so the provider call is refused rather than charging a different account's quota.
Source
Thrown at src/main/codex-accounts/service.ts:556
private validateResetCreditScope(
expectedScope: CodexResetCreditExpectedScope,
requireCurrentOffer: boolean
): { managedHomePath: string; rateLimits: RateLimitState } {
const rateLimitState = this.rateLimits.getState()
if (!sameRateLimitTarget(rateLimitState.codexTarget, expectedScope.target)) {
throw new CodexResetCreditScopeRejection(
'targetChanged',
rateLimitState,
'The active Codex rate-limit target changed before reset.'
)
}
const settings = this.store.getSettings()
if (
getSelectedCodexAccountIdForTarget(settings, expectedScope.target) !== expectedScope.accountId
) {
throw new CodexResetCreditScopeRejection(
'accountChanged',
rateLimitState,
'The selected Codex account changed before reset.'
)
}
const account = settings.codexManagedAccounts.find(
(candidate) => candidate.id === expectedScope.accountId
)
if (!account || account.updatedAt !== expectedScope.accountRevision) {
throw new CodexResetCreditScopeRejection(
'accountRevisionChanged',
rateLimitState,
'The selected Codex account was updated before reset.'
)
}
const normalizedAccountTarget = normalizeCodexAccountSelectionTarget(
getCodexSelectionTargetForAccount(account)
)View on GitHub (pinned to 1136503c6a)
Solutions
- Re-select expectedScope.accountId for that target (setSelectedCodexAccountIdForTarget) and replay the idempotency key.
- If the selection change is intended, discard this attempt and start a new one scoped to the now-selected account.
- For fresh attempts, consume the rejectedBeforeProvider result and re-trigger from the current selection.
Example fix
// before: account switched under a pending reset service.consumeRateLimitResetCredit(key, scopeForAccountA) // rejects accountChanged // after: re-select the scope's account, then replay await service.selectAccountForTarget(scope.accountId, scope.target) await service.consumeRateLimitResetCredit(key, scope)
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the scope's account is still selected for this target.
const selected = getSelectedCodexAccountIdForTarget(store.getSettings(), scope.target)
if (selected !== scope.accountId) {
// re-select or rebuild scope for the now-selected account before calling
} Try / catch
try {
await service.consumeRateLimitResetCredit(key, scope)
} catch (error) {
if (error instanceof CodexResetCreditScopeRejection && error.reason === 'accountChanged') {
// either re-select scope.accountId or rebuild scope for current selection
} else throw error
} Prevention
- Disable account switching in the UI while a reset is in flight.
- Rebuild expectedScope from the live selection right before consuming.
When it happens
Trigger: A reset is in flight or replayed, but the user (or a queued mutation) changed which managed Codex account is selected for that target — e.g. selectAccount/selectAccountForTarget ran between scope capture and validateResetCreditScope.
Common situations: User clicks the account switcher while a reset is pending; or a doSelectAccount mutation serialized ahead of the reset's validateResetCreditScope call. Also when a replayed durable attempt wakes up after selection drifted.
Related errors
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/4221f46bead69719.
Report an issue: GitHub.