Skip to content

Reset-derived 429 in an OpenAI combo blocks same-account fallback models #590

Closed

Description

@akrock

Client or integration

Codex App, using OpenCodex subagent routing through defined multi model combo in failover mode: combo/sub.

Area

Proxy and routing. The affected state is the shared Codex account-pool cooldown.

Summary

A 429 from the first OpenAI target in a failover combo is promoted to a hard cooldown for the entire Codex-login account. That prevents the combo from trying later fallback models that use the same account.

In my case, the first target was a Spark model with exhausted quota. The intended fallback path was Terra/Luna. The upstream availability is model-specific for this workflow, but the proxy stores the 429 as account-wide reset-derived state. Subsequent Terra/Luna attempts return a local 429 before reaching upstream.

I expected the failover combo to try the later models, or for a reset-only 429 to remain a short, probeable target/model-level avoidance rather than blocking the account.

Reproduction

  1. Configure the canonical openai provider with Codex-login pool mode and the main account.
  2. Configure a failover combo for subagents whose first target is a quota-limited Spark model and whose later targets are Terra/Luna under the same openai provider.
  3. Send a subagent request through combo/sub after the Spark target begins returning 429 responses with Codex reset headers but no explicit Retry-After.
  4. Observe the first 429 set account health to reset-derived.
  5. Observe later same-account fallback attempts return OpenCodex's local Selected Codex account (main) is cooling down 429 instead of reaching Terra/Luna.
  6. Run ocx account clear-cooldown openai main or restart the proxy. The later models work again.

The issue is especially easy to trigger when multi-agent work sends several same-account OpenAI requests concurrently.

Version

@bitkyc08/opencodex 2.7.41

Operating system

macOS 26.4.1

Provider and model

Canonical OpenAI Codex-login provider in pool mode. A failover combo was ordered Spark → Terra/Luna; all targets used the same openai account.

Logs or error output

2026-07-28T02:44:33.645Z: originating combo 429

Selected Codex account (main) is cooling down until 2026-07-28T02:59:33.645Z (source: reset-derived).
Run 'ocx account list openai' to find the id, then 'ocx account clear-cooldown openai <id>' to lift it, or switch accounts with 'ocx account use openai <id>'.

The deadline is exactly 15 minutes after the originating failure, matching the reset-derived cooldown cap. During that interval, later same-account fallback requests fail locally. Restarting works because account-health state is process-local.

Screenshots and supporting files

The request-log and error-detail screenshots show interleaved successful and 429 OpenAI attempts during the multi-agent burst, followed by the combo/sub error above. They can be supplied if maintainers need them.

Redacted configuration

{
  "providers": {
    "openai": {
      "adapter": "openai-responses",
      "baseUrl": "https://chatgpt.com/backend-api/codex",
      "authMode": "forward",
      "codexAccountMode": "pool"
    }
  },
  "combos": {
    "sub": {
      "strategy": "failover",
      "targets": [
        { "provider": "openai", "model": "Spark target" },
        { "provider": "openai", "model": "Terra target" },
        { "provider": "openai", "model": "Luna target" }
      ]
    }
  }
}

Additional implementation context

The combo child enters the normal Responses pipeline, whose canonical OpenAI target records the 429 against the shared account. The #433 recovery path only permits one probe after five minutes; ordinary 200 responses preserve the existing hard cooldown. This leaves a substantial window where same-account combo fallback cannot occur.

Related: #433.

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

Activity

  1. github-actions commented on Jul 28, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  2. github-actions commented on Jul 28, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

  3. Ingwannu commented on Jul 28, 2026

    @Ingwannu
    Owner

    Confirmed against the current dev request path.

    A pre-stream 429 can record a reset-header-derived hard cooldown on the shared Codex account before the parent combo advances. The later target then fails locally during auth resolution even when it is a different model on the same OpenAI provider.

    I am implementing a narrow request-scoped fix: defer only reset-derived account cooldown recording when a later same-provider failover target exists. Explicit Retry-After cooldowns and the conservative default cooldown will remain account-wide and blocking, while the failed combo target will still receive its normal target cooldown. I will add regression coverage for both the allowed model fallback and the explicit-Retry-After blocking case, plus the routing decision documentation.

  4. Ingwannu commented on Jul 28, 2026

    @Ingwannu
    Owner

    Fixed on dev in commit 7710185c.

    For ordered failover combos, a reset-header-derived pre-stream 429/402 now permits a later eligible model on the same OpenAI provider to run in the same request. The failed physical model target still receives its normal combo cooldown. Explicit Retry-After and headerless/default quota cooldowns remain account-wide and block another same-account dispatch.

    Regression coverage proves both sides: Spark reset-derived 429 → Terra success with two upstream sends, and explicit Retry-After → one upstream send with the second model blocked locally. The full pre-push suite passed: 5,700 tests, TypeScript typecheck, GUI lint, and privacy scan.

    This will be included in the next release cut from dev.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions