Skip to content

fix(combos): one Anthropic account's 402 credit refusal cools the account, not the combo target - #7204

Closed
vadymhimself wants to merge 3 commits into
lidge-jun:devfrom
vadymhimself:fix/combo-anthropic-pool-402-account-scope
Closed

vadymhimself wants to merge 3 commits into
lidge-jun:devfrom
vadymhimself:fix/combo-anthropic-pool-402-account-scope

Conversation

@vadymhimself

@vadymhimself vadymhimself commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Verification

  • Red/green: bun test tests/adapters/anthropic/anthropic-combo-account-cooldown.test.ts. The new 402 test fails on clean dev 60bf4c7 (target cooled) and passes here 5/5 runs. The added exhausted-pool test fails if the sibling-eligibility guard is removed (mutation-checked).
  • bun run typecheck: clean.
  • bun run structure:check: passed. structure/runtime.md documents the 402 case next to the fix(combos): a spent generic OAuth account cools the account, not the combo target #7191 text.
  • bun run privacy:scan: passed.
  • bun run test:changed (the core-combo graph covers 1739 files): 38223 pass, 27 fail, 3 errors. Every failure is in tests/cli/cli-access-audio-live, cli-connect-readiness, ocx-launcher-runtime, codex-integration/codex-runtime, native-codex-toggle, native-grok-toggle, and tests/service/*. Rerun in isolation, those 9 files give the identical 7 failures on clean dev and on this branch. The rest are load-dependent under the full parallel run. No combo, routing, or Anthropic test fails.
  • The full bun run test has not been run locally.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved combo failover for account-specific failures: eligible OAuth accounts returning 429 and Anthropic accounts with credit-balance errors can be skipped while other accounts remain available.
    • Combo targets are cooled when no eligible account remains, helping subsequent requests follow the appropriate fallback behavior.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

@vadymhimself

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: a5e0a666-5f39-4cd3-98e8-e8ea0a551b91
📥 Commits

Reviewing files that changed from the base of the PR and between 60bf4c7 and 223b855.

📒 Files selected for processing: 8
  • scripts/test-layout/layout.json
  • src/combos/resolve.ts
  • src/server/responses/core-combo.ts
  • structure/runtime.md
  • tests/adapters/anthropic/anthropic-combo-account-cooldown.test.ts
  • tests/fixtures/test-layout-expected.json
  • tests/oauth/generic-oauth-combo-account-cooldown.test.ts
  • tests/oauth/generic-oauth-failover.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📝 Walkthrough

Combo failure handling now identifies qualifying account-level failures for generic OAuth 429 responses and Anthropic OAuth credit-balance 402 responses. It records account refusals and applies combo-target cooldowns based on whether an eligible sibling account remains.

Changes: Combo Account Cooldown Handling

Layer / File(s) Summary
Account failure attribution and rotation
src/server/responses/core-combo.ts, src/combos/resolve.ts
Failure classification records qualifying Anthropic OAuth 402 refusals and rotates a uniquely identified generic OAuth account for target-scoped 429 responses. Account-scoped failure handling now includes identified-account 402 responses.
Cooldown tests and runtime contract
tests/oauth/generic-oauth-combo-account-cooldown.test.ts, tests/adapters/anthropic/anthropic-combo-account-cooldown.test.ts, tests/oauth/generic-oauth-failover.test.ts, structure/runtime.md, scripts/test-layout/layout.json, tests/fixtures/test-layout-expected.json
Tests cover generic OAuth 429 rotation and Anthropic OAuth 402 refusals when a sibling account is or is not eligible. The runtime contract and test-layout mappings are updated.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CoreCombo as core-combo
  participant OAuthPool as Generic OAuth account pool
  participant Fallback as Fallback target
  Client->>CoreCombo: Send combo request
  CoreCombo->>OAuthPool: Request through selected account
  OAuthPool-->>CoreCombo: Return target-scoped 429
  CoreCombo->>OAuthPool: Rotate failed account using Retry-After
  OAuthPool-->>CoreCombo: Identify eligible sibling or no sibling
  CoreCombo->>Fallback: Continue when the selected target fails
  Fallback-->>Client: Return fallback response
Loading

Suggested reviewers: lidge-jun

Merge Risk: ⚪ Minimal · up to 223b8

This change handles account-level credit refusals and generic OAuth rate limits more precisely in combos. No concrete merge-blocking risk was identified in the supplied context.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 5 files. (3 skipped: 3… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the primary Anthropic OAuth 402 account-refusal behavior. It matches the implemented change and does not need to mention the additional generic OAuth 429 hand…
Full details: Docstring Coverage

Explanation

Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 5 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Oct 15, 2026
@vadymhimself
vadymhimself force-pushed the fix/combo-anthropic-pool-402-account-scope branch from 223b855 to 70b25a3 Compare October 15, 2026 20:35
vadymhimself and others added 2 commits October 16, 2026 06:52
… combo target

The per-request account budget can end a generic OAuth pool's rotation
before it reaches every stored account, so a 429 reaches the combo layer
while a sibling is still healthy. The combo then cooled the whole target
for that account's Retry-After (up to the 24h server-delay ceiling) and
sent traffic to the fallback target, or answered 503.

Resolve the refused account from the child's accountLogLabel and hand it
to the pool's own rotator, which cools it under the pool's Retry-After
policy. The target is spared only when the rotator names an eligible
sibling; a lone account or a fully cooled pool still cools the target.
Anthropic OAuth and Codex attribution are unchanged. API-key pools need
no change: their 429 rotation walks every key inside the attempt.

Co-Authored-By: Claude Code <noreply@anthropic.com>
…ount, not the combo target

The Anthropic OAuth pool rotates only on 401/403/429, so a 402 carrying the
credit-balance refusal reaches the combo with the refused account still
selectable. The combo classifies 402 as provider-scoped and cooled every
anthropic target in the combo, sending traffic to the fallback (or a
zero-attempt 503) while a sibling account still answered.

When the failed child identifies one pool account and the failure carries the
exact credit-balance wording, record that account's refusal through the pool's
own recordAnthropicAccountRefusal (the entitlement backoff a 403 credit
refusal already gets) and skip the target cooldown only while the pool still
has an eligible account. A lone account, an exhausted pool, an unidentified
account and every other 402 keep the provider-scoped cooldown.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@vadymhimself
vadymhimself force-pushed the fix/combo-anthropic-pool-402-account-scope branch from 70b25a3 to 0dadd7f Compare October 15, 2026 22:54
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • hygiene: unsponsored_surface.

What to do

  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/generic-account-failover.ts.
  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ⬜ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.
@vadymhimself Tick the boxes once required local validation has passed with commands, results, and any full-suite exception documented, your branch is on the latest dev commit, and every correct Codex and CodeRabbit finding is resolved.

@lidge-jun

Copy link
Copy Markdown
Owner

Being carried into #7224 with your authorship preserved; this PR will be closed when the bundle lands.

The combo layer asks the generic OAuth rotator only whether a healthy
sibling exists; it never dispatches to the account the rotator names.
Under pool.kernel round-robin the rotator committed that pick, advancing
the ring and making it sticky to an account no request was sent to.

Add a `commit` flag to rotateGenericOAuthAccountOn429 (default true).
The combo passes false: the failed account is still cooled, but the ring
is only peeked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Oct 16, 2026
lidge-jun added a commit that referenced this pull request Oct 16, 2026
…evidence fixes (#7191, #7204, #7187, #7209, #7175, #7185, #7193, #7197, #7198) (#7224)

Carried from #7191, #7204, #7187, #7209, #7175, #7185, #7193, #7197, #7198 (one commit per source PR, original author preserved). Security review follow-up: the Anthropic 402 combo cooldown now validates the sending credential's ownership before cooling an account.

Remote validation (hosted GitHub Actions unreliable; local tests not run by maintainer rule): union candidate codex/prr-integ-8 = dev c03eafd + #7224 + #7223 + #7225 + #7217 + #6454 + #6594 plus a Gentle Shell import-cycle fix (integ-9 e1f289c: typecheck + full suite on mini (Windows) and lidge (Linux), compared with the same host's dev runs) and a test-only Windows path-escaping fix for the reasoning-retention routing test (integ-10 0d4cba7, tree a2b309a: that file re-run on both hosts).

Co-authored-by: Vadym O <bolein95@gmail.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Landed on dev in 6ccb47a via #7224 (your change is its own commit in that bundle, and the squash keeps your authorship as Co-authored-by). Thank you!

@lidge-jun lidge-jun closed this Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants