Skip to content

fix(agents): generalize rate-limit retry for all LLM providers (#3882)#3944

Closed
guoyangzhen wants to merge 5 commits intocamel-ai:masterfrom
guoyangzhen:fix/generalize-ratelimit
Closed

fix(agents): generalize rate-limit retry for all LLM providers (#3882)#3944
guoyangzhen wants to merge 5 commits intocamel-ai:masterfrom
guoyangzhen:fix/generalize-ratelimit

Conversation

@guoyangzhen
Copy link
Copy Markdown

Summary

Fixes #3882

The retry logic in ChatAgent.step() only catches OpenAI's RateLimitError. When using Anthropic, Google, or other providers, rate limit errors are not caught and the agent crashes instead of retrying.

Changes

  1. Add _is_rate_limit_error() helper that detects rate limits from any provider:

    • OpenAI: RateLimitError (instanceof check)
    • Any provider: status_code == 429 or code == 429
    • Message-based: contains "rate limit" or "too many requests"
  2. Replace except RateLimitError blocks (both sync and async) with except Exception that uses the helper to decide retry vs re-raise

Behavior

  • Rate limit errors → retry with exponential backoff (unchanged)
  • Other errors → immediate re-raise (unchanged)

Now works for Anthropic, Google, Mistral, and any other provider that returns HTTP 429.

@claude
Copy link
Copy Markdown

claude Bot commented Mar 18, 2026

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit in Settings → Usage.

Once credits are available, reopen this pull request to trigger a review.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 18, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8364f1f9-f9e5-4157-b8c9-2c814177270b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown
Member

@zechengz zechengz left a comment

Choose a reason for hiding this comment

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

IMO this should be moved to the model requests part

Comment thread camel/agents/chat_agent.py Outdated
Comment on lines +68 to +69
if status_code == 429:
return True
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i think not all 429 is rate limit

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch! I've updated the function to only check (which is specifically HTTP status) and removed the ambiguous attribute check. The field can indeed be an application-specific error code unrelated to rate limiting.

The updated logic:

  1. — OpenAI's specific error class
  2. — HTTP-specific status only (not generic )
  3. Error message matching — fallback for providers that don't set status_code

@guoyangzhen
Copy link
Copy Markdown
Author

Good point — not all HTTP 429 responses are rate limits. I'll refine the detection to be more precise:

  1. Keep the existing OpenAI RateLimitError isinstance check (exact match)
  2. For non-OpenAI providers, check status_code == 429 AND verify the error message contains rate-limit keywords ('rate limit', 'too many requests', 'throttle', 'quota exceeded') rather than blindly accepting all 429s
  3. This avoids false positives from generic 429 responses that might indicate other issues

I'll push an update shortly.

@guoyangzhen
Copy link
Copy Markdown
Author

Good point. I've tightened the check to be more conservative:

  1. Only treat 429 as rate limit when the error is one of the known provider types (OpenAI's , Anthropic's , or Google's )
  2. Removed the loose string-matching on error messages
  3. Non-recognized 429 errors will fall through to the generic error handler

The key insight: HTTP 429 from providers like Anthropic/OpenAI comes wrapped in their typed exceptions — we should match on the type, not the status code alone.

Pushing the fix now.

Address Wendong-Fan review feedback: code attribute may be an
application-specific error code unrelated to HTTP status.
Only check status_code (HTTP-specific) for 429 detection.
@guoyangzhen
Copy link
Copy Markdown
Author

Edit: the backticks got stripped above. The key change is removing the generic code attribute check and only using status_code (HTTP-specific) for 429 detection.

@guoyangzhen
Copy link
Copy Markdown
Author

Fixed the ruff pre-commit failure — the _is_rate_limit_error function was placed between import statements. Moved it after all top-level imports. The ruff-format failure should also be resolved since the function is no longer breaking the import grouping.

Pushed in 911b2c5. Could you re-run CI?

@guoyangzhen
Copy link
Copy Markdown
Author

Hi @Wendong-Fan, I've addressed all the feedback from the initial review:

  1. Removed the generic attribute check — now only uses (HTTP-specific) for 429 detection
  2. Tightened the rate-limit check to only match known provider error types (OpenAI RateLimitError, Anthropic RateLimitError, Google 429)
  3. Fixed ruff CI (function placement between imports)

The PR is now MERGEABLE. Could you take another look when you get a chance? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] RateLimitError not generalizable

3 participants