Repository navigation
Description
Client or integration
Codex CLI
Area
Authentication and account pool
Summary
When the main account's usage is reset early, outside opencodex (a reset credit redeemed somewhere other than ocx account reset-credits), the main-account hard lock keeps refusing every native request locally until the previously predicted reset time, which can be days away. Nothing in the default configuration ever re-reads usage in that state, so the lock only clears when someone opens the dashboard or runs ocx account refresh openai.
Why it cannot notice the early reset:
- While
codexMainAccountHardLockblocks, requests are refused locally (5–140 ms,failureStage: headers-only), so no upstream response can carry fresh usage. runMainAccountHardLockRecovery()returns before probing whenever the blocking window's reset is still in the future (src/codex/auth-api/pool-mode-gate.ts:104ondev: "A predicted reset is a scheduling hint, never proof that the hard lock can be lifted."). This wait is intentional (fix(codex): pace quota recovery queries #6179) and covered byknown reset waits locally, then verifies recovery instead of unlocking by timeintests/codex-integration/main-account-hard-lock-recovery.test.ts.- The only other periodic reader,
src/quota/reset-poller.ts, does nothing unlessquotaResetNotifyis enabled, and it is disabled by default. - Redeeming through opencodex is fine:
consumeResetCredits()callsrefreshAfterManualReset()and publishes fresh usage. The gap is a reset that happens anywhere else (Codex App, web, or an upstream-side reset), which the "wait for the predicted reset" assumption does not cover.
So the design assumption "usage cannot drop before the known reset" no longer holds once reset credits exist, and the lock can outlive the real block by up to a weekly window.
Expected: an early reset should be noticed within a bounded time without user action. Some options, in order of how little they change:
- While blocked with a future reset, still allow the recovery sweep to read WHAM usage on a slow, capped cadence (for example every 30–60 minutes, reusing the existing
nextQuotaQueryDelay/ Retry-After pacing), instead of not at all until the reset. - Or treat a non-zero
resetCreditscount on the main account as "an early reset is possible" and only then enable that slow probe. - At minimum, surface it in the 429 message: the current text suggests waiting or disabling the lock, but not that
ocx account refresh openaiclears a stale block.
Reproduction
- Use the main (native Codex login) account until the hard lock blocks (here, observed message:
Codex main account is blocked by the main-account quota policy (5h ≥ 90%, weekly ≥ 98%)). - Redeem a reset credit outside opencodex (here, not via
ocx account reset-credits; the ocx service log has no reset-credit call). - Send Codex CLI requests through opencodex: every native OpenAI model returns local
429 rate_limit_exceeded(observed forgpt-6-luna,gpt-5.6-luna,gpt-6.1-sol,gpt-6-astra, 59 of 59 recent native requests), while non-OpenAI providers keep returning 200. - Run
ocx account refresh openai: it reportsweekly 3%, and the next Codex CLI request returns 200 immediately.
I could not recover the exact pre-refresh cached quota tuple (the cache file was overwritten by the refresh), so which window was blocking and its stored reset time are not shown here.
Version
opencodex 2.83.0 (npm @bitkyc08/opencodex); the same code path is unchanged on dev as of 2026-10-17. Codex CLI 0.163.0.
Operating system
macOS (Darwin 25.5.0, arm64)
Provider and model
openai (native Codex main account, Pro plan) — gpt-6.1-sol, gpt-6-luna, gpt-5.6-luna, gpt-6-astra
Logs or error output
status: 429, durationMs: 14, errorCode: rate_limit_exceeded, failureStage: headers-only
upstreamError: Codex main account is blocked by the main-account quota policy (5h ≥ 90%, weekly ≥ 98%). Choose another account, wait for quota to reset, or disable codexMainAccountHardLock in Settings.
routeDecision.selected: { provider: openai, model: gpt-6-luna, reason: native-family }
After ocx account refresh openai:
main pro weekly 3% resets 2026-10-24T22:01:09.000Z
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
Ingwannu commentedon Oct 18, 2026
Confirmed the scheduling gap statically on dev
8640c2f30edb:runMainAccountHardLockRecoveryhas both a pre-acquisition and a pre-query future-reset return. Requests refused by the lock cannot refresh it through inference headers. The missing pre-refresh tuple limits attribution of the historical 59 requests to one exact blocking window, but does not remove this deterministic early-reset case.The existing hard-lock diagnostic guide already lists
ocx account refresh openaias a metadata refresh: fresh below-threshold usage or validated window absence releases the lock. It is not an unconditional unlock, and disabling the policy is not required when fresh evidence proves recovery.A runtime fix changes the deliberate known-reset scheduling contract from #6179, so it needs an owner decision on a bounded metadata-only recheck cadence. Do not unlock by elapsed time, issue inference, spend/redeem credits, or rely on a cached positive reset-credit count as the only permission to discover an external reset. Reuse the current single-flight/profile lease, identity+credential/config fencing and shared Retry-After/query backoff. Test a future known reset whose injected metadata drops early, repeated sweeps without duplicate reads, failed/incomplete observations retaining the lock, pauses/reauth, credential replacement and stale completion. A successful later observation must clear only the matching physical account. Keep unknown/no-reset recovery and credit-renewal behavior as controls.
Leaving this bug open for that scheduling decision; #7290 concerns stored-pool credit evidence and is not a duplicate. No real usage query, reset redemption or local configuration change was executed in this triage.
fix(codex): renew pool credit evidence, recheck predicted-reset hard …
lidge-jun commentedon Oct 19, 2026
Fixed on dev by #7393 (squash d3dafd3): a predicted reset now arms a capped, metadata-only WHAM recheck schedule (5/10/20/40, then at most every 60 min; no inference, no reset redemption, paused/needs-reauth main excluded), so an early reset redeemed outside opencodex is learned from verified metadata. A predicted reset alone still never lifts the lock. It ships in the next release (2.90.0).
github-actions commentedon Oct 19, 2026
Automated translation bookkeeping — detected language: English.
JHulsinger commentedon Oct 21, 2026
The 2.90.0 fix still leaves users locked out for 5–60 minutes after an external reset. Suggest checking live usage before refusing.
What happened (2.84.0)
shortPercent: 90, which trips the default hard lock. I redeemed a reset outside opencodex.failureStage: "headers-only"). The same request sent directly tochatgpt.com/backend-api/codexsucceeded.Suggestions
UsageRelayController.rewriteJsonalready parses into the quota store the hard lock reads.