Skip to content

[Bug]: Codex pool registration couples account persistence to warmup success #3846

Description

@shaun0927

Client or integration

OpenCodex dashboard

Area

Authentication and account pool

Summary

I experienced a registration failure when adding a Codex pool account whose weekly allowance was exhausted. Source inspection confirms a blocking path: after OAuth completes, account registration requires a successful inference warmup, and any warmup failure stops pool-account persistence.

Expected behavior: an authenticated, identity-verified account can be registered as quota-limited, without being marked inference-ready or selected for requests until recovery. Registration should preserve the account for later use without changing the provider's usage limits.

This is a request to revise an existing validation policy, not a claim that the warmup gate was accidental. The confirmed scope is the Codex pool registration path; other providers have not been shown to share this defect.

Reproduction

Scenario to confirm with a live account:

  1. Use a ChatGPT account whose Codex weekly allowance is already exhausted.
  2. Add that account through the dashboard Codex account-pool OAuth flow.
  3. Complete OAuth successfully.
  4. If the subsequent warmup returns a quota rejection, the login flow becomes error before the new pool account is persisted.

Evidence boundary: the registration failure was experienced by the reporter on a real exhausted account. The installed source and current dev gate were inspected, but no live exhausted-account response was captured and no behavioral reproduction test was executed for this report. The exact upstream rejection shape in this incident remains unconfirmed.

The source explains how this can occur:

  • warmup.ts sends a real /backend-api/codex/responses request and requires response.completed. Non-2xx responses and streamed response.failed, response.incomplete, or error events fail verification. Only HTTP 400 has the fallback-model retry.
  • auth-api.ts calls verifyCodexAccountWarmup before persisting the pool account. A failed result sets the OAuth login state to error and exits. Its generic message asks the user to reauthenticate even when the cause can be quota or availability.

Version

Installed package inspected: @bitkyc08/opencodex 2.45.0.

The blocking gate is also present on inspected dev commit 5fdf9bbdd9ff7657f0b6d7101697317d708af0e7.

Operating system

Windows 11 Pro, version 10.0.26200. The inspected warmup/registration gate has no OS-specific branch; macOS/Linux execution was not tested.

Provider and model

OpenAI / ChatGPT Codex account pool. The inspected warmup defaults to gpt-5.4-mini, with gpt-5.5 as a fallback for HTTP 400. This concerns account registration rather than a user-selected conversation model.

Logs or error output

No live account log is attached. The source-generated message is:

Codex account warmup failed. Reauthenticate the account and try again.

For an HTTP 429 warmup rejection, the code appends (http_status:429). Streamed quota rejections can instead become a stream failure reason; HTTP 429 must not be assumed to be the only quota signal.

Historical decision and related work

The July 5 warmup design and implementation record explains the original objective: metadata lookup success did not prove that a Codex Responses request would work. It explicitly includes HTTP 429/5xx among warmup failures, considers saving with an unknown warmup status for transient failures, and records an implementation that does not add the account when warmup fails.

The proposed change preserves that distinction: stored/authenticated must not imply inference-ready.

Suggested fix

Separate credential/identity verification, account persistence, and inference readiness in the Codex add/reauth flow:

  1. Preserve OAuth, identity matching, duplicate checks, and existing credential generation/locking protections.
  2. When authentication and identity are established independently and the probe is classified as quota-limited, persist the account with that restriction. Do not record a successful inference-validation timestamp or mark it healthy.
  3. Keep the account ineligible for routing until quota recovery is confirmed. Preserve the restriction through restart and handle unknown reset times explicitly.
  4. Show an actionable quota-limited result instead of asking for reauthentication. Keep invalid credentials and identity mismatches on their existing rejection paths.
  5. Classify provider responses using HTTP status plus bounded structured error/terminal evidence. Do not treat every 429/403 as proof of valid authentication, and preserve the secret-safe error handling from fix(codex): bound warmup response bodies #1725.

Transport failures and unsupported-model responses should remain distinct from quota and authentication failures; changing their persistence policy can be a separate follow-up. A scoped Codex fix can reuse existing account-health concepts without claiming all providers need the same change.

Suggested regression coverage:

  • Successful OAuth + completed warmup retains normal registration behavior.
  • Independently authenticated account + HTTP quota rejection is stored as quota-limited and cannot route.
  • A structured streamed quota rejection follows the same path; an unrelated incomplete stream does not.
  • Invalid authentication and mismatched identity are still rejected.
  • Same-identity reauthentication while quota-limited follows the intended credential-replacement contract without marking inference validation successful.
  • Restart and quota-refresh failures do not silently turn the restricted account healthy; confirmed recovery restores eligibility.

Maintainer alignment requested: is the registration/readiness distinction acceptable as a revision of the July policy? Any implementation PR would target dev and follow the authentication-area sponsorship requirement.

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