[Bug] Stale Codex resets_at blocks paid account failover after the account is already usable

Author: ramapitecusmentCreated Sep 1, 2026Updated Sep 15, 2026
Labelspending

Is it a request payload issue?

  • Yes
  • No, it is a persisted Codex quota/cooldown issue.

Describe the bug

A paid Codex OAuth account can remain excluded from routing until an old usage_limit_reached.resets_at deadline even after the same account is accepted by upstream again.

In a two-account pool, account B was kept in a persisted model cooldown. When account A later exhausted its quota, failover failed because both credentials were considered locally unavailable. Restarting CLIProxyAPI did not help because save-cooldown-status: true restored the cooldown. Toggling account B disabled -> active cleared the local state, and the next request through account B immediately returned HTTP 200, about 98 hours before the cached deadline.

No upstream quota reset, OAuth re-login, token refresh, or credential replacement was performed during recovery; the logs show only Management API status PATCHes.

Timeline (local time, UTC+4)

2026-08-31 01:05:14 account B upstream 429:
  type=usage_limit_reached plan_type=pro
  resets_at=1788643357 (2026-09-06 01:22:37 +04)
  resets_in_seconds=519443
  -> local cooldown=144h17m22s

2026-09-01 22:32:07 account A upstream 429:
  type=usage_limit_reached plan_type=pro
  resets_at=1788747928 (2026-09-07 06:25:28 +04)
  resets_in_seconds=460401

2026-09-01 22:32:19 selector:
  2 of 2 candidates are in cooldown
  account A remaining=127h53m08s
  account B remaining=98h50m17s

2026-09-01 23:36:37 CLIProxyAPI 7.2.147 restarted
2026-09-01 23:37:50 both cooldowns were restored; account B remaining=97h44m46s

2026-09-01 23:47:10 PATCH /v0/management/auth-files/status (account B disabled)
2026-09-01 23:47:11 PATCH /v0/management/auth-files/status (account B active)
2026-09-01 23:47:17 selector chose account B
2026-09-01 23:47:19 POST /v1/responses -> HTTP 200

This confirms that the cached paid-plan deadline no longer represented actual upstream availability, while CLIProxyAPI had no request path that could observe the recovery.

Expected behavior

A paid Codex credential that becomes usable before an old advertised deadline should eventually be reconsidered without requiring an operator to clear its cooldown manually. This should be bounded/backed off rather than a tight polling loop.

Actual behavior

parseCodexRetryAfter uses the full future resets_at, the model state is persisted to .cds, restored after restart, and filtered before any upstream request. request-retry cannot help because no eligible credential reaches the executor.

CLI Type

Codex OAuth, two ChatGPT Pro accounts.

Model Name

gpt-5.6-sol

LLM Client

Codex app / codex-tui 0.151.0, Responses API.

Request Information

POST /v1/responses. This is not payload-dependent; consecutive requests were rejected locally in 8-16 ms while both auths were in cooldown. The first request after clearing only the local auth state succeeded through upstream in 1.895 s.

Environment

  • CLIProxyAPI 7.2.147, commit 17a65ee5
  • macOS 26.6.2, arm64
  • routing.strategy: fill-first
  • save-cooldown-status: true
  • disable-cooling: false
  • request-retry: 3
  • WebSocket-capable Codex OAuth auths

Related

  • #5277 describes stale cooldown after an explicit upstream quota reset; it was closed in favor of manual POST /v0/management/reset-quota.
  • #4248 already proposes a bounded paid-plan recheck. This report provides a current v7.2.147 real-world reproduction where no upstream reset action was performed and stale cooldown prevented two-account failover.

Source: router-for-me/CLIProxyAPI