fix(proxy): report eligible pool usage exhaustion as 429 - #1541
Open
Soju06 wants to merge 14 commits into
Open
Conversation
Owner
Author
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d73fd3869d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Collaborator
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The takeover of #1247 hardens selection_failure_response: instead of a private duplicate of the account-cap code set, local capacity codes are resolved via app.core.resilience.overload.LOCAL_OVERLOAD_CODES. This keeps every local overload code (including codes added later, such as the congestion fair-share code from #1536) on the stable 429 rate_limit_error contract, and guarantees the new usage_limit_reached 429 mapping is applied strictly to upstream usage/quota exhaustion of the whole eligible pool. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds externally-routed regressions for the takeover of #1247: - /v1/responses and /backend-api/codex/responses return HTTP 429 with error.type = error.code = usage_limit_reached (and authoritative error.resets_at) when every eligible account is usage-exhausted - resets_at is omitted when selection has no authoritative reset - paused/deactivated/reauth-only pools keep the pre-existing no_accounts semantics, and the synthetic SSE failure keeps the #1479 sequenced response.created/response.failed SDK stream contract - one usable account still fails over with no error Also tightens the OpenSpec delta: authoritative-reset-only resets_at, terminal (non-waitable) usage-limit failures, local capacity codes keep their rate_limit_error contract, owner-scoped exhaustion keeps continuity semantics. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Soju06
force-pushed
the
fix/pool-usage-exhaustion-429
branch
from
August 4, 2026 07:41
acbf7a4 to
9eb44ab
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When every account eligible for a Responses request is exhausted by an upstream usage/quota window, codex-lb previously collapsed the failure into a generic
502/503no_accounts, which makes Codex mark persisted Goalsblockedinstead ofusageLimited. This change classifies pool-wide exhaustion structurally (no retry-text parsing) and returns the Codex-compatible contract:{"error": {"message": "…", "type": "usage_limit_reached", "code": "usage_limit_reached"}}with HTTP
429, pluserror.resets_atonly when account selection holds an authoritative upstream reset for an actually exhausted window (never the capped human retry hint or a synthesized fallback).Closes #1246.
Supersedes #1247 — original implementation by @glopyglerky, taken over per the 07-27 maintainer notice. The author's 10 commits are preserved with original authorship; takeover commits sit on top.
Behavior matrix (#1246)
429 usage_limit_reached(+ authoritativeresets_at)no_accountssemanticsLOCAL_OVERLOAD_CODESmember, including codes added later such asapi_key_stream_fair_sharefrom feat(proxy): congestion-aware per-API-key fair-share stream admission #1536) → existing429 rate_limit_error502429 usage_limit_reachedRebase notes
mainacross the_load_balancer/package extraction, fix(proxy): spill unanchored forks on account caps #1499 (unanchored-fork spillover) and fix(proxy): release idle bridge sessions' account stream leases #1476 (idle bridge lease release); the author's balancer-loop changes were ported intounbound_selection.py/sticky_selection.py.429exits as an HTTP response before_normalize_public_responses_stream; streamed selection failures keep the sequenced syntheticresponse.created→response.failedcontract (pinned by integration test).selection_failure_responseresolves local capacity codes against the canonicalLOCAL_OVERLOAD_CODESregistry so the new 429 mapping is strictly for upstream usage exhaustion.OpenSpec
openspec/changes/report-pool-usage-exhaustion/(delta onresponses-api-compat), extended for authoritative-reset-onlyresets_at, terminal usage-limit failures, local-capacity contract preservation, and owner-scope continuity.openspec validate report-pool-usage-exhaustion --strictpasses.Testing
ruff check+ruff format --check+scripts/check_proxy_architecture.py+uv run ty check: passtests/unit/test_load_balancer*.py,test_selection_errors.py,test_openai_errors.py,test_proxy_http_bridge.py,test_proxy_utils.py,tests/integration/test_proxy_responses.py,test_http_responses_bridge.py,test_proxy_api_extended.py— 1,919 tests passed/v1/responsesand/backend-api/codex/responses,resets_atpresence/omission, and the fix(proxy): sequence synthetic Responses failures #1479 sequenced SSE failure contract.🤖 Generated with Claude Code