{"record":{"id":"ab4cebde7f8b7180","repo":"stablyai/orca","slug":"accountrevisionchanged","errorCode":"accountRevisionChanged","errorMessage":"The selected Codex account was updated before reset.","messagePattern":"The selected Codex account was updated before reset\\.","errorType":"exception","errorClass":"CodexResetCreditScopeRejection","httpStatus":null,"severity":"warning","filePath":"src/main/codex-accounts/service.ts","lineNumber":566,"sourceCode":"        'The active Codex rate-limit target changed before reset.'\n      )\n    }\n\n    const settings = this.store.getSettings()\n    if (\n      getSelectedCodexAccountIdForTarget(settings, expectedScope.target) !== expectedScope.accountId\n    ) {\n      throw new CodexResetCreditScopeRejection(\n        'accountChanged',\n        rateLimitState,\n        'The selected Codex account changed before reset.'\n      )\n    }\n    const account = settings.codexManagedAccounts.find(\n      (candidate) => candidate.id === expectedScope.accountId\n    )\n    if (!account || account.updatedAt !== expectedScope.accountRevision) {\n      throw new CodexResetCreditScopeRejection(\n        'accountRevisionChanged',\n        rateLimitState,\n        'The selected Codex account was updated before reset.'\n      )\n    }\n    const normalizedAccountTarget = normalizeCodexAccountSelectionTarget(\n      getCodexSelectionTargetForAccount(account)\n    )\n    if (!sameRateLimitTarget(normalizedAccountTarget, expectedScope.target)) {\n      throw new CodexResetCreditScopeRejection(\n        'accountRuntimeChanged',\n        rateLimitState,\n        'The selected Codex account belongs to a different runtime.'\n      )\n    }\n\n    const currentScope = buildCodexResetCreditExpectedScope({\n      target: rateLimitState.codexTarget,","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/codex-accounts/service.ts#L548-L584","documentation":"A CodexResetCreditScopeRejection with reason 'accountRevisionChanged'. The account record still exists but its updatedAt timestamp no longer matches expectedScope.accountRevision. The revision is part of the scope key, so any mutation to the account (re-authentication, email/identity refresh) invalidates an in-flight reset to prevent acting on stale identity.","triggerScenarios":"The account was updated (doReauthenticateAccount bumps updatedAt at service.ts:876, or any field changed) after the scope was captured but before the provider reset validates. The persisted account.updatedAt diverges from expectedScope.accountRevision.","commonSituations":"User re-authenticates the account while a reset is queued; the mutation queue runs the re-auth first, bumping updatedAt, so the reset's captured revision is now stale.","solutions":["Capture a fresh expectedScope from the current account (its new updatedAt) and start a new attempt.","Avoid mutating the account (re-auth/edit) while a reset is in flight; serialize these operations at the UI layer.","For fresh attempts, treat the rejectedBeforeProvider result as 'discard and re-trigger'."],"exampleFix":"// before: replaying scope captured before a re-auth bumped updatedAt\nservice.consumeRateLimitResetCredit(key, oldScope) // rejects accountRevisionChanged\n\n// after: rebuild scope carrying the new accountRevision\nconst account = service.listAccounts().accounts.find(a => a.id === id)!\nconst scope = buildCodexResetCreditExpectedScope({ target, account, limits })!\nawait service.consumeRateLimitResetCredit(crypto.randomUUID(), scope)","handlingStrategy":"validation","validationCode":"// Recapture the account revision right before consuming.\nconst account = service.listAccounts().accounts.find(a => a.id === scope.accountId)!\nif (account.updatedAt !== scope.accountRevision) {\n  // rebuild scope with the new revision before calling\n}","typeGuard":null,"tryCatchPattern":"try {\n  await service.consumeRateLimitResetCredit(key, scope)\n} catch (error) {\n  if (error instanceof CodexResetCreditScopeRejection && error.reason === 'accountRevisionChanged') {\n    // rebuild scope from the current account.updatedAt\n  } else throw error\n}","preventionTips":["Do not re-authenticate or edit an account while its reset is pending.","Always read account.updatedAt from listAccounts() at scope-build time."],"tags":["codex-accounts","rate-limit-reset","scope-rejection","account-revision"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}