[Bug] Anthropic pool quota exhaustion is returned as retryable rate_limit_exceeded, so Codex retries and shows 'exceeded retry limit, 429' instead of a usage-limit message
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start with the cooldown handling in src/oauth/anthropic-routing.ts and the response paths in src/server/responses/adapter-dispatch.ts and src/server/responses/passthrough-dispatch.ts; then inspect the Codex account path in src/codex/auth-context.ts. Check how cooldown sources and reset times reach error responses, and run the proposed tests for reset-derived and retry-after cooldowns. Done means quota exhaustion returns usage_limit_reached with resets_at while short throttles remain rate_limit_exceeded.
Written by the indexing model from the issue text.
Description
Client or integration
Codex App
Area
Authentication and account pool
Summary
When every Anthropic OAuth account in the pool is out of its five-hour or weekly quota, OpenCodex answers Codex with HTTP 429 rate_limit_error / rate_limit_exceeded. Codex treats that class as transient, keeps retrying ("reconnecting 1/5 ... 5/5") and ends with exceeded retry limit, last status: 429 Too Many Requests. The user sees a long "thinking" state and never learns that the quota is spent or when it resets.
I expected the same terminal class that OpenAI returns for a spent plan: usage_limit_reached with resets_at. Codex renders that class as "Usage limit reached ... try again at " and stops at once.
This is the Anthropic-pool form of #6000, which was closed automatically for the issue template and not fixed.
Reproduction
- Configure an Anthropic OAuth account pool and let every account reach its five-hour (or weekly) limit.
- Send a Codex turn with
anthropic/claude-opus-5-5. - Observe: the pool logs
no eligible replacement; returning 429, and every later turn is refused locally in 2-9 ms withrate_limit_exceeded. Codex retries each turn (one conversation logged 16 refused requests) and shows only the retry-limit message.
Version
2.83.0
Operating system
macOS (Bun 1.4.2), Codex 0.162.1
Provider and model
anthropic / claude-opus-5-5 (any Anthropic OAuth pool model)
Logs or error output
[anthropic-pool] 429 on <account-a>; failing over to <account-b>
[anthropic-pool] no eligible replacement; returning 429
usage.jsonl: provider=anthropic status=429 errorCode=rate_limit_exceeded failureCause=rate-limit durationMs=2..9 (78 rows)
Codex: exceeded retry limit, last status: 429 Too Many Requests
Source-level analysis (v2.83.0)
src/oauth/anthropic-routing.ts:75-80:AnthropicAccountCooldownError("All Anthropic OAuth accounts are temporarily rate-limited"). The pool already knows each cooldown source (retry-after,reset-derived,default, lines 84-100), so it knows when a cooldown is a drained quota window and when it resets.src/server/responses/adapter-dispatch.ts:518-520andsrc/server/responses/passthrough-dispatch.ts:951-953turn that error intoformatErrorResponse(429, "rate_limit_error", ...)withRetry-After.src/lib/errors.ts:448-458maps every 429 torate_limit_exceeded. The quota information is lost here.- The comment at
adapter-dispatch.ts:521-524says "the Codex client ... does not retry a 429", but Codex 0.162.1 does retryrate_limit_exceededand ends with the retry-limit message.
Proposed change
- When
AnthropicAccountCooldownErrorfires and every blocking cooldown isreset-derived(quota window), return HTTP 429 witherror.type = "usage_limit_reached",resets_at= earliest reset (epoch seconds), and a message that names the provider and the reset time. Keeprate_limit_exceededfor shortretry-afterthrottles. - Apply the same rule to the Codex-account cooldown path (
src/codex/auth-context.ts:946). - Test: a reset-derived cooldown yields
usage_limit_reached+resets_at; a retry-after cooldown yieldsrate_limit_exceeded+Retry-After.
Related: #6989 (Retry-After-sourced cooldowns not recovering).
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
- Dominant language
- TypeScript
- Stars
- 16.9k
- Forks
- 1.3k
- Avg merge
- 7h 38m
- Merged PRs (30d)
- 659
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lidge-jun/opencodex
-
account-pool bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
lidge-jun/opencodex#7440 · 2 comments ·
Maintainers usually reply within 1 day
-
[Docs]: translate the #7395 OpenGateway and Mistral provider-guide sectionsPossibly taken @MannXo claimed this today. Opendocumentation
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
lidge-jun/opencodex#7405 · 3 comments ·
Maintainers usually reply within 1 day
-
bug cli
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
lidge-jun/opencodex#7403 · 2 comments ·
Maintainers usually reply within 1 day
-
account-pool enhancement needs-design proxy
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
lidge-jun/opencodex#6737 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement proxy
Difficulty 4/5 1-2 days Newbie friendliness 55/100
lidge-jun/opencodex#7443 · 3 comments ·
Maintainers usually reply within 1 day
All issues in lidge-jun/opencodex
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
getsentry/sentry-conventions#732 · 1 comment ·
Maintainers usually reply within 1 day
-
status:in-linear status:team-assigned team:nodes
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
n8n-io/n8n#41548 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
motiondivision/motion#3955 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
equinor/prisma-decision-web#919 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 83/100