Skip to content

fix(proxy): harden Anthropic request and retry handling - #1165

Merged
murdore merged 1 commit into
releasefrom
fix/proxy-rate-limit-hardening
Jul 15, 2026
Merged

murdore merged 1 commit into
releasefrom
fix/proxy-rate-limit-hardening

Conversation

@murdore

@murdore murdore commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • preserve genuine Claude Code OAuth request bodies instead of reordering system identity blocks or relocating their instructions
  • classify Anthropic construction rejections separately from genuine rate limits and finalize them exactly once
  • publish transient cooldowns before retrying, share retry budgets across concurrent requests, and pace requests waiting for short cooldown recovery
  • keep authoritative quota cooldowns reset-aware, skip fallback for deterministic invalid requests, and improve stream transport diagnostics without duplicate terminal telemetry

Evidence

A direct A/B replay used the same captured request, account, endpoint, and headers:

  • original Claude Code body: HTTP 200, with 5h and 7d quota explicitly allowed
  • proxy-mutated body: HTTP 429 with rate_limit_error: Error and no genuine rate-limit headers
  • patched transformation is byte-identical to the accepted original body

A later incident reproduced the same result with a different captured request.

Validation

  • 210/210 Vitest tests
  • 118/118 environment guard checks
  • 89/89 production bugfix checks
  • pnpm typecheck
  • pnpm build:cli
  • full pre-commit check, lint, validation, security scan, package build, browser build, and publint

The live proxy was not modified or restarted during development or verification.

Summary by CodeRabbit

  • Bug Fixes
    • Improved temporary rate-limit handling by coordinating retries and smoothing recovery when accounts are cooling down.
    • More consistent streaming error reporting that preserves underlying transport details.
    • Certain “construction rejection” 429 responses are now treated as non-retryable terminal errors (mapped to a terminal failure instead of rate limiting).
    • Preserved genuine Claude Code identity blocks while keeping custom instructions formatted consistently.
    • Prevented deterministic invalid requests from triggering unnecessary provider fallback.
  • Tests
    • Expanded reliability and OAuth/streaming error coverage for rate-limit coordination, cooldown pacing, terminal error handling, and fallback gating.

Copilot AI review requested due to automatic review settings July 15, 2026 09:18
@vercel

vercel Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
neurolink Ready Ready Preview, Comment Jul 15, 2026 11:16am

@github-actions

github-actions Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

✅ Single Commit Policy - COMPLIANT

Status: Policy requirements met • 1 commit • Valid format • Ready for merge

📊 View validation details

📝 Commit Details

  • Hash: ac62eb49215e2a209b61c710b27f9470f4ec0963
  • Message: fix(proxy): harden Anthropic request and retry handling
  • Author: Sachin Sharma

✅ Validation Results

  • Single commit requirement met
  • No merge commits in branch
  • Semantic commit message format verified
  • Ready for squash merge to release branch

🤖 Automated validation by NeuroLink Single Commit Enforcement

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a4e2747f-4043-4ea1-b302-b22c6d55257b

📥 Commits

Reviewing files that changed from the base of the PR and between 11d666b and ac62eb4.

📒 Files selected for processing (4)
  • src/lib/server/routes/claudeProxyRoutes.ts
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-bugfixes.ts
  • test/proxyReliabilityHardening.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-bugfixes.ts
  • test/proxyReliabilityHardening.test.ts

📝 Walkthrough

Walkthrough

Claude proxy routing now preserves Claude Code OAuth request structure, coordinates transient 429 retries and cooldown admissions, classifies construction rejections as terminal invalid requests, gates fallback, and standardizes nested transport-error reporting.

Changes

Claude proxy reliability

Layer / File(s) Summary
OAuth request normalization
src/lib/server/routes/claudeProxyRoutes.ts, test/proxyReliabilityHardening.test.ts
Claude Code identity blocks are preserved, while custom instructions are relocated and wrapped during OAuth body preparation.
Transient rate-limit coordination
src/lib/types/proxy.ts, src/lib/server/routes/claudeProxyRoutes.ts, test/proxyReliabilityHardening.test.ts, test/continuous-test-suite-bugfixes.ts
Shared retry budgets and cooldown admission schedules pace concurrent transient 429 retries and account selection.
Terminal rejection and fallback routing
src/lib/types/proxy.ts, src/lib/server/routes/claudeProxyRoutes.ts, test/proxyReliabilityHardening.test.ts
Construction-rejection 429s produce terminal invalid-request responses and deterministic failures bypass fallback.
Stream error reporting and validation
src/lib/server/routes/claudeProxyRoutes.ts, test/proxyReliabilityHardening.test.ts
Nested transport errors are described consistently across stream paths, with updated lifecycle and telemetry assertions.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant RoutedRequestLoop
  participant TransientCooldownAdmission
  participant AnthropicUpstream
  Client->>RoutedRequestLoop: submit Claude-compatible request
  RoutedRequestLoop->>TransientCooldownAdmission: check account availability
  TransientCooldownAdmission-->>RoutedRequestLoop: paced retry admission
  RoutedRequestLoop->>AnthropicUpstream: send normalized request
  AnthropicUpstream-->>RoutedRequestLoop: response or classified terminal error
  RoutedRequestLoop-->>Client: stream or finalized proxy error
Loading

Possibly related PRs

  • juspay/neurolink#1143: Both changes update upstream 429 cooldown planning, retry pacing, and account selection.
  • juspay/neurolink#1163: Both changes modify routing-loop 429 handling, stream error telemetry, and credential retry behavior.

Suggested reviewers: pdogra1299

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main proxy request and retry hardening changes without being overly broad or misleading.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/proxy-rate-limit-hardening

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: private package registry requires authentication. Disable ESLint in CodeRabbit settings or use public packages.


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.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the Anthropic/Claude proxy’s request transformation and retry/cooldown behavior, focusing on preserving genuine Claude Code OAuth request shapes, correctly classifying “construction” 429s vs real rate limits, and reducing retry amplification under concurrent load.

Changes:

  • Preserve genuine Claude Code system block ordering/content for OAuth, while continuing to relocate non-Claude client system instructions into messages.
  • Introduce shared transient 429 retry budgets and paced admission during short transient cooldowns to avoid concurrent retry herds.
  • Add a dedicated terminal error path for construction rejections, improve stream transport error diagnostics, and skip provider fallback for deterministic invalid requests.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/proxyReliabilityHardening.test.ts Adds coverage for OAuth request-shape preservation, 429 classification, shared transient retry budgets, transient cooldown pacing, fallback skipping, and stream transport error descriptions.
test/continuous-test-suite-bugfixes.ts Updates invariant string checks to reflect let effectiveAccounts change.
src/lib/types/proxy.ts Extends proxy types to support shared transient retry budget state and a fetch-layer terminal error handoff.
src/lib/server/routes/claudeProxyRoutes.ts Implements request-shape preservation tweaks, terminal construction rejection finalization, shared transient retry/cooldown pacing, improved stream diagnostics, and invalid-request fallback suppression.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/server/routes/claudeProxyRoutes.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/proxyReliabilityHardening.test.ts (1)

885-891: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert terminal telemetry behavior instead of source text.

Checking for one function name can still pass when another path emits duplicate terminal telemetry. Drive a failed stream and assert the final logger, tracer, and usage statistics each settle once.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/proxyReliabilityHardening.test.ts` around lines 885 - 891, Replace the
source-text assertion in the “uses only canonical terminal telemetry for stream
failures” test with an end-to-end failed-stream scenario. Assert that the final
logger, tracer, and usage-statistics handlers each settle exactly once, covering
all terminal telemetry paths rather than checking only for the absence of
logStreamError.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/server/routes/claudeProxyRoutes.ts`:
- Around line 5081-5105: The post-refresh path in handleAnthropicAuthRetry must
reuse the existing construction_rejection terminal mapping from the anti-abuse
429 branch in src/lib/server/routes/claudeProxyRoutes.ts:5081-5105, returning a
non-retryable 400 with the same error body, headers, logging, tracing, and loop
termination behavior. Add an auth-retry or route-level regression in
test/proxyReliabilityHardening.test.ts:157-230 proving that an anti-abuse 429
after OAuth refresh is finalized as a 400 rather than retried.

---

Nitpick comments:
In `@test/proxyReliabilityHardening.test.ts`:
- Around line 885-891: Replace the source-text assertion in the “uses only
canonical terminal telemetry for stream failures” test with an end-to-end
failed-stream scenario. Assert that the final logger, tracer, and
usage-statistics handlers each settle exactly once, covering all terminal
telemetry paths rather than checking only for the absence of logStreamError.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b8456673-40ad-4263-b269-c68ee66a7851

📥 Commits

Reviewing files that changed from the base of the PR and between 426c17d and 11d666b.

📒 Files selected for processing (4)
  • src/lib/server/routes/claudeProxyRoutes.ts
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-bugfixes.ts
  • test/proxyReliabilityHardening.test.ts

Comment thread src/lib/server/routes/claudeProxyRoutes.ts Outdated
@murdore

murdore commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the CodeRabbit review-body test nit in ac62eb4 as well: the prior source-text assertion was replaced with a behavioral failed-stream test that consumes the stream and verifies exactly one final request log, one tracer error/end, one upstream span end, and one request/error stats increment.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@murdore
murdore merged commit 1b455cb into release Jul 15, 2026
17 checks passed
@murdore
murdore deleted the fix/proxy-rate-limit-hardening branch July 15, 2026 12:29
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.87.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@Tara-ag Tara-ag left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Reviewed the 4 changed files in this already-merged PR. No new blocking issues were identified beyond the points already raised and resolved by prior reviewers.

Files reviewed

  • src/lib/server/routes/claudeProxyRoutes.ts
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-bugfixes.ts
  • test/proxyReliabilityHardening.test.ts

Existing review points (already handled)

  • Billing-block ordering for synthesized Claude Code identity blocks — addressed by author.
  • Post-OAuth-refresh construction-rejection terminal 400 path — addressed by author with matching regression test.

Assessment

  • The construction-rejection classification now correctly bypasses rate-limit accounting and returns a non-retryable 400 in both the initial-fetch and auth-retry paths.
  • Shared transient retry budgets and paced cooldown admission are bounded and reset-aware.
  • Stream transport errors are described once and terminal telemetry settles exactly once.
  • Provider fallback is correctly gated on invalidRequestFailure === null.
  • Types and test coverage are aligned with the runtime changes.

New issues raised this review: 0 critical, 0 major, 0 minor.

Approving.

This branch was successfully deployed

1 active deployment
Preview — ac62eb49 Deployed Jul 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants