Skip to content

bug(codex): automatic quota activation stalls after reset #3855

Description

@terrytan95

Client or integration

Codex App

Area

Authentication and account pool

Summary

Automatic quota-window activation can remain enabled while no new window is activated after reset. Three related gaps exist in v2.45.0 and remain in the current dev implementation:

  1. A successful warmup records the completed reset but discards the response's quota headers. Without unrelated traffic or dashboard quota reads, subsequent sweeps keep seeing the completed old timestamp and do not activate the next idle window.
  2. Failed activation records only a retry delay. Re-reading quota can replace the expired reset with a future idle-window reset, so the retry no longer finds a due window. There is no retained pending boundary.
  3. A time-valid but upstream-rejected bearer is reused by the warmup path. An inference 401 neither enters authentication recovery nor marks that credential for reauthentication; failures are swallowed into another five-minute retry.

Expected: opted-in idle accounts keep scheduling successive observed windows, pending activation survives metadata changes, and rejected credentials have a bounded recovery or actionable reauthentication outcome. Failures should expose a safe diagnostic reason.

Reproduction

Enable both automatic windows for an added Codex account in canonical OpenAI Pool mode. Keep the account unpaused and run the proxy continuously.

Scenario A — consecutive idle windows:

  1. Supply an expired 5-hour quota snapshot to the activation worker.
  2. Let the minimal warmup complete, including quota headers identifying the next 5-hour reset.
  3. Produce no unrelated account traffic or dashboard quota refresh.
  4. Advance beyond the next reset and run the worker again. Only the first inference was sent; the quota cache still contains the original completed boundary.

Scenario B — lost retry:

  1. Run an enabled expired weekly window and make warmup fail, for example with 429.
  2. Before the five-minute retry, let a quota read report an idle weekly reset in the future.
  3. Run the worker after its retry delay. It no longer attempts the pending activation.

Scenario C — rejected but locally time-valid bearer:

  1. Use a fixture credential whose expiresAt is in the future.
  2. Make the Codex Responses endpoint return 401.
  3. Run the worker at the due time and five minutes later. The same bearer is sent twice, with no recovery request and needsReauth still false.

These scenarios were reproduced with the actual v2.45.0 worker/warmup code and injected upstream responses in an isolated temporary home. No real inference, reset-credit redemption, or account mutation was used for the investigation.

Separately, read-only observation of a real opted-in account returned HTTP 401 with token_revoked while its local expiry remained in the future. Another account's unused weekly window repeatedly reported reset_after_seconds=604800 and a reset_at that moved with query time. These observations support the relevant failure conditions; absent activation logs prevent claiming an exact historical sequence for every affected account.

Version

2.45.0; official tag b0900e5. The same activation implementation is present at dev 6cf38b5.

Operating system

macOS 27.0; Bun 1.4.0

Provider and model

Canonical openai provider, Codex Pool mode; default warmup gpt-5.4-mini, with the existing gpt-5.5 fallback on HTTP 400.

Logs or error output

v2.45.0 isolated observations:
first reset: warmupRequests=1; cached reset unchanged
next reset after five idle hours: warmupRequests=1
same tick after external quota refresh: warmupRequests=2

failed due request, then future weekly metadata:
attempts=1; nextTickDue=null

401 with locally time-valid credential:
inference requests=2; sameBearer=true; needsReauth=false

The worker does not currently log the caught activation failure.

Screenshots and supporting files

Source references: src/codex/quota-auto-refresh.ts (due selection, warmAccount, completion/retry), src/codex/warmup.ts (success headers and HTTP failures), src/codex/account-store.ts (expiresAt shortcut). The existing 64 focused worker/warmup/lifecycle checks passed during the v2.45.0 audit but do not cover these combined scenarios.

Redacted configuration

{
  "defaultProvider": "openai",
  "providers": {
    "openai": {
      "adapter": "openai-responses",
      "baseUrl": "https://chatgpt.com/backend-api/codex",
      "authMode": "forward",
      "codexAccountMode": "pool"
    }
  },
  "codexAccounts": [{ "id": "pool-fixture", "isMain": false, "plan": "team" }],
  "codexQuotaAutoRefresh": {
    "pool-fixture": { "fiveHour": true, "weekly": true }
  }
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions