fix(review): stop retrying an AI provider 429 immediately with zero backoff#5481
Conversation
…ackoff runWorkersOpinion, runDualAiTieBreakJudgeCall, runWorkersSlopOpinion, and runPlannerModel each retry a failed model call up to 3x (2x for the planner) before falling through to the fallback model -- but a rate-limit error (claude_code_error_429 / ai_http_429 / anthropic_http_429) will not have cleared by the next attempt a few hundred ms later, so retrying the SAME model burns the whole per-model attempt budget for zero additional chance of success, delaying (or in the tie-break/slop/planner loops, which had no special-casing at all, fully exhausting before) the fallback model ever gets a turn. Adds isRateLimitError (exported from ai-review.ts, shared by ai-slop.ts and planner.ts) and applies the same short-circuit runWorkersOpinion already uses for a non-transient CLI timeout: break out of the current model's retry loop on a 429 and move straight to the fallback, which may be on a different provider/account entirely. Fixes GITTENSORY-K Fixes GITTENSORY-8
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5481 +/- ##
=======================================
Coverage 94.73% 94.73%
=======================================
Files 561 561
Lines 44794 44798 +4
Branches 14667 14671 +4
=======================================
+ Hits 42437 42441 +4
Misses 1622 1622
Partials 735 735
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-12 23:15:26 UTC
⏸️ Suggested Action - Manual Review Review summary Blockers
Nits — 5 non-blocking
Concerns raised — review before merging
📋 Copy for AI agents — paste into your coding agent
Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
…nion too Gittensory review flagged that linked-issue-satisfaction-run.ts's own env.AI.run() retry loop was missed by the original fix -- it still burned its full per-model attempt budget on a claude_code_error_429 before falling back, same as the four loops already fixed.
Summary
Sentry issues GITTENSORY-K (
selfhost_ai_provider_failed: claude_code_error_429, 2090 occurrences over 2 weeks) and GITTENSORY-8 (ai_review_provider_exhausted: claude_code_error_429, 328 occurrences) are a genuine external Anthropic rate limit — that part is expected. But every retry loop that callsenv.AI.run()for the claude-code provider (runWorkersOpinion,runDualAiTieBreakJudgeCall,runWorkersSlopOpinion,runPlannerModel) retries the SAME model immediately with zero backoff on a 429, even though the rate-limit window it just hit cannot possibly have cleared a few hundred milliseconds later — burning the whole per-model attempt budget for zero additional chance of success, and delaying (or, for the tie-break/slop/planner loops, which had no special-casing at all before this) the fallback model's turn.Changes
isRateLimitError(exported fromsrc/services/ai-review.ts, matchingclaude_code_error_429/ai_http_429/anthropic_http_429), shared byai-slop.tsandplanner.tsinstead of each re-deriving its own copy.runWorkersOpinionalready uses for a non-transient CLI timeout (isSubscriptionCliTimeout) to a rate-limit error too: break out of the current model's retry loop and move straight to the fallback, which may be on a different provider/account entirely.runWorkersOpinionandrunDualAiTieBreakJudgeCall(src/services/ai-review.ts),runWorkersSlopOpinion(src/services/ai-slop.ts),runPlannerModel(src/review/planner.ts).src/services/ai-summaries.tshas no retry loop at all today (single unretried attempt) — left out of scope for this fix; flagged as a possible separate follow-up.Test plan
npm run typecheck— cleannpm run test:ci(full local gate, unsharded coverage) — greenFixes GITTENSORY-K
Fixes GITTENSORY-8