Custom providers can show quota warnings from the local ChatGPT account

Open 💬 2 comments Opened Jul 19, 2026 by MeroZemory

Summary

When Codex is configured with a custom model provider whose requests use credentials/account separate from the local ChatGPT login, proactive quota notices can still be driven by the local ChatGPT account.

For example, Codex may show:

Heads up, you have less than 10% of your weekly limit left.

even though the active custom provider is routing the request through a different account with sufficient quota.

Reproduction

  1. Log Codex in to a ChatGPT account so that ~/.codex/auth.json contains local account state.
  2. Configure and select a custom model provider with requires_openai_auth = false.
  3. Have that provider send inference requests using separate credentials/account.
  4. Let the locally logged-in ChatGPT account approach its rate limit while the account actually selected by the provider still has sufficient quota.
  5. Run a model turn through the custom provider.

The TUI can show a proactive low-quota warning based on the local account rather than the account that served the turn.

Expected behavior

  • Local ChatGPT account snapshots must not drive proactive quota warnings when the active provider does not require OpenAI authentication.
  • Rate-limit metadata returned with the active model turn should still drive accurate warnings for the account/provider that actually served the request.
  • OpenAI-specific lower-cost model-switch nudges should not be shown for custom providers.
  • Correct warnings should not require an additional quota API request on every turn; Codex should use metadata already present on the successful turn response.

Root cause

The notice path treats local AccountUsage snapshots and turn-derived RollingUpdate snapshots equivalently. Their provenance matters:

  • AccountUsage represents the locally logged-in ChatGPT account.
  • RollingUpdate comes from the active model turn response.

For a custom provider, only the latter can describe the quota state of the provider/account that actually served the request.

Validated patch

I prepared and tested a minimal patch that scopes notices by snapshot provenance and provider authentication behavior:

Added tests:

  • custom_provider_ignores_local_account_rate_limit_notices
  • custom_provider_warns_from_turn_rate_limits_without_model_nudge

Verification:

  • Targeted tests: 2/2 passed
  • Full codex-tui: 3,145/3,146 passed
  • just fix -p codex-tui: passed
  • just fmt: passed

The one full-suite failure is an unrelated existing Windows-only pet image assertion:

pets::tests::kitty_local_file_pet_image_uses_file_reference_without_inline_payload

That test uses absence of the literal Base64 substring cG5n as a proxy for ensuring the bytes b"png" were not sent inline. However, the local-file protocol intentionally Base64-encodes the canonical file path, and a Windows path ending in frame.png can legitimately contain the same substring depending on Base64 alignment. The output still uses Kitty's file-transfer mode (t=f), and this patch does not touch the pet/image code.

PR availability

The repository currently limits opening pull requests to collaborators, so I could not open the PR directly. The compare link above is ready for a maintainer/collaborator to use.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗