Skip to content

[Bug]: pool quota WHAM 401 bypasses stored-token refresh after plan changes #3019

Description

@luvs01

Client or integration

OpenCodex dashboard

Area

Authentication and account pool

Summary

A stored Codex pool account can retain a bearer whose JWT expiry is still in the future while the upstream service rejects that bearer after a subscription or account-plan transition. The account-list quota path calls WHAM with that bearer and immediately reports needsReauth: true on HTTP 401. It does not use the bounded stored-token recovery already used by the Responses/compact request path.

The expected behavior is one forced refresh for the rejected credential generation, followed by one WHAM replay with the rotated bearer. OpenCodex should require manual reauthentication only when the refresh grant or a structured WHAM response provides terminal revocation/expiry evidence. A bare second 401 should remain transient rather than being mislabeled as token expiry.

This is adjacent to, but not covered by, #2887/#2889: those changes recover Responses/compact requests. It is also distinct from #3003, which throttles repeated failed quota-prime calls without refreshing a WHAM-rejected pool bearer.

Reproduction

  1. Add a Codex-login account to the stored account pool and confirm that its refresh grant works.
  2. Change that account's subscription or plan in a way that causes the upstream service to rotate or reject the current access bearer while the stored JWT exp remains in the future.
  3. Refresh the Codex authentication dashboard, or request GET /api/codex-auth/accounts?refresh=1.
  4. Observe that the WHAM quota request returns HTTP 401 and the account DTO reports needsReauth: true / token expired without attempting the stored-token forced refresh.
  5. Reauthenticate the same account manually and repeat the account-list request. The account works again and its current plan/quota can be read, showing that the previous classification was not proof that the refresh grant had expired.

Version

2.36.0; the missing recovery path was also confirmed on dev before the proposed fix.

Operating system

Windows 11 24H2

Provider and model

OpenAI Codex login; model-independent account quota lookup

Logs or error output

GET /api/codex-auth/accounts?refresh=1
WHAM quota lookup: HTTP 401
account result: needsReauth=true, quotaError=token_expired

Screenshots and supporting files

No attachment is required; the regression is covered with redacted in-process HTTP fixtures.

Redacted configuration

{
  "codexAuth": {
    "mode": "pool"
  }
}

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