stablyai/orca · warning · CodexResetCreditScopeRejection
targetChanged
targetChanged
Error message
The active Codex rate-limit target changed before reset.
What it means
A CodexResetCreditScopeRejection with reason 'targetChanged', thrown by validateResetCreditScope. The runtime target currently reported by rateLimits.getState().codexTarget (its runtime + wslDistro) no longer equals expectedScope.target. The reset credit is bound to a specific runtime, so the provider call is refused before it starts to avoid charging the wrong target's credit.
Source
Thrown at src/main/codex-accounts/service.ts:545
attempt.promise = null
},
() => {
attempt.promise = null
if (attempt.state === 'fresh') {
this.releaseFreshResetAttempt(idempotencyKey, attempt)
}
}
)
return promise
}
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.accountIdView on GitHub (pinned to 1136503c6a)
Solutions
- Rebuild the expectedScope from the CURRENT rateLimits.getState().codexTarget and start a fresh attempt with a new idempotency key.
- If the target change was unintentional, restore the previously-active target (distro/runtime) and replay the same idempotency key.
- For fresh attempts, the rejection is returned as a rejectedBeforeProvider result with retryDisposition 'discardAttempt' (service.ts:476) — discard and let the user re-trigger from the current target.
Example fix
// before: replaying a stale scope after runtime switched
service.consumeRateLimitResetCredit(oldKey, staleScope) // rejects targetChanged
// after: rebuild scope from current target
const state = rateLimits.getState()
const scope = buildCodexResetCreditExpectedScope({ target: state.codexTarget, account, limits: state.codex })!
await service.consumeRateLimitResetCredit(crypto.randomUUID(), scope) Defensive patterns
Strategy: validation
Validate before calling
// Rebuild the scope from the CURRENT target right before consuming.
const { codexTarget } = rateLimits.getState()
const scope = buildCodexResetCreditExpectedScope({ target: codexTarget, account, limits: rateLimits.getState().codex })
if (!sameRateLimitTarget(codexTarget, scope!.target)) {
throw new Error('target drifted; refresh and retry')
}
await service.consumeRateLimitResetCredit(crypto.randomUUID(), scope!) Type guard
const isSameTarget = (a: RateLimitRuntimeTarget, b: RateLimitRuntimeTarget): boolean => a.runtime === b.runtime && a.wslDistro === b.wslDistro
Try / catch
try {
await service.consumeRateLimitResetCredit(key, scope)
} catch (error) {
if (error instanceof CodexResetCreditScopeRejection && error.reason === 'targetChanged') {
// rebuild scope from current target and retry once with a fresh key
} else throw error
} Prevention
- Capture the scope immediately before consuming it, not from a cached snapshot.
- Block target/runtime switching while a reset is pending.
When it happens
Trigger: Consuming a reset credit (consumeRateLimitResetCredit replay, or a fresh startResetCreditAttempt) after the active Codex rate-limit target changed between when the scope was captured and when validation runs — e.g. the user switched the active WSL distro or moved from host to WSL runtime mid-flow.
Common situations: User toggles the runtime/distro selector, or an external CODEX_RUNTIME/WSL_DISTRO change flips codexTarget while a reset is queued behind the mutation queue. Also after an app restart that rehydrates a providerPending attempt whose target is no longer active.
Related errors
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/17c6b368e7c1de15.
Report an issue: GitHub.