Skip to content

Fail over to the next combo target when a target rejects a request for context length (HTTP 400) instead of failing the request #7443

Closed

Description

@RHODIZSECURITY

Area

Proxy and routing

What are you trying to accomplish?

Run long agentic coding sessions through combo routes whose targets have heterogeneous context windows (1M-class targets alongside 131k/250k targets), so a large request that one target cannot accept can still be served by another target of the same combo whose window fits it.

What prevents this today?

The combo failover rotates on 410 and on 429, but a target's HTTP 400 "Please reduce the length of the messages or completion" (surfaced as upstream_error -> invalid_request_error) is treated as a fatal client error and returned to the caller even when untried targets remain in the combo. Observed on OpenCodex 2.84.0 (Linux): a request with ~336k tokens of context walked the combo (410 from one target, 429 from two others) and then died on the length 400; the proxy journal logged [opencodex] upstream failure code=invalid_request_error as the turn failed, killing the client session's turn even though the same combo contained 1M-window targets. A per-target limitation (this target's window is smaller than the request) is misclassified as a per-request error (as if the request were malformed for every target).

What should OpenCodex do?

Treat a context-length 400 from a target as a failure OF THAT TARGET: record it, apply the normal target cooldown, and continue failover to the next target. Fail the request only after all targets are exhausted. Where the proxy already knows each target's declared context window, it could additionally skip targets whose window cannot hold the request, but rotating on the length-400 alone would already fix the failure mode.

Example usage or interface

Combo route: [provider-a/model-small (131k window), provider-b/model-large (1M window)]
Request (~336k tokens) -> model-small -> 400 "Please reduce the length of the messages or completion"
  -> rotate -> model-large -> 200 OK
Today: the 400 is returned to the client as invalid_request_error and the turn dies.

No configuration change should be required; this is the observable failover behaviour for a target-scoped error.

Alternatives or workarounds

Restricting every combo to largest-window targets only (drops useful smaller or cheaper targets), manually splitting combos by expected request size, or lowering the client-side auto-compaction threshold so requests never exceed the smallest target's window — which wastes the larger targets' windows and fragments routing.

Additional context

Related to #7426 (rotate on HTTP 429): both ask the combo layer to classify target-scoped failures as retryable against the next candidate instead of failing the whole request. Observed in production on OpenCodex 2.84.0 (Linux) fronting Codex traffic. Reported by RHODIZ IT LLC.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

  1. github-actions commented on Oct 20, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

  2. added
    enhancementNew feature or request
    proxyHTTP proxy, routing, reverse-proxy / management auth
    on Oct 20, 2026
  3. github-actions commented on Oct 20, 2026

    @github-actions
    Contributor

    Possibly related issues:

    Detected automatically via GitHub Copilot; automatic closure requires separate deterministic evidence.

  4. Ingwannu commented on Oct 20, 2026

    @Ingwannu
    Owner

    Checked against trusted dev 12025981e5a304cdb6b1b54f525ba8554f623977. Current failover already hops on definite context overflow after cancellation/non-replayable guards, using bounded innermost-message classification in combos/failover.ts. The quoted "Please reduce the length of the messages or completion" is not itself in that definitive phrase vocabulary. Please supply the exact redacted structured leaf code/message and wrapper shape from a current version, without the prompt. A targeted additional classifier must prove target context refusal and preserve malformed-JSON, contradictory-code, ordinary invalid-parameter and committed-output negatives. Do not turn every invalid_request_error/400 into a hop or impose a long target cooldown from one oversized request.

  5. lidge-jun commented on Oct 30, 2026

    @lidge-jun
    Owner

    Resolved on dev by #7892 (524c019c7b). PRs into dev do not auto-close linked issues, so this was closed manually. The fix ships with the next release cut from dev; please reopen if it still reproduces on a build that contains it.

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

    enhancementNew feature or requestproxyHTTP proxy, routing, reverse-proxy / management auth

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions