Skip to content

fix: surface provider-specific rate limit error message (#54433)#54512

Merged
altaywtf merged 3 commits intoopenclaw:mainfrom
bugkill3r:fix/surface-provider-rate-limit-message
Mar 26, 2026
Merged

fix: surface provider-specific rate limit error message (#54433)#54512
altaywtf merged 3 commits intoopenclaw:mainfrom
bugkill3r:fix/surface-provider-rate-limit-message

Conversation

@bugkill3r
Copy link
Copy Markdown
Contributor

Summary

Test plan

  • Configure a provider that returns rate limit errors with specific messages
  • Verify the specific message is shown to the user instead of the generic one

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: S labels Mar 25, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 25, 2026

Greptile Summary

This PR surfaces actionable provider-specific rate-limit messages (e.g. reset times, plan names, quota details) to the user instead of always showing the generic "⚠️ API rate limit reached. Please try again later." copy.

The approach is clean: a new extractProviderRateLimitMessage helper uses the existing parseApiErrorInfo function to extract a human-readable message from JSON payloads, falls back to the raw string for plain-text errors, and then gates on RATE_LIMIT_SPECIFIC_HINT_RE to ensure only messages that contain actionable detail (time hints, plan/quota mentions) are promoted. The generic fallback is preserved when no specific detail is present.

Key observations:

  • The existing formatRateLimitOrOverloadedErrorCopy call-site in sanitizeUserFacingText also benefits from the change automatically since it calls the same helper.
  • Tests are well-targeted: JSON payload path, plain-text path, and the do-nothing (generic) path are all exercised.
  • One minor UX edge-case: for plain-text rate-limit messages that include a leading HTTP status code (e.g. "429 Your quota is exhausted, try again in 24 hours") and are not JSON, the "429 " prefix is not stripped before constructing the user-facing string, resulting in "⚠️ 429 Your quota is exhausted…". This is cosmetic and does not affect correctness.

Confidence Score: 4/5

  • Safe to merge; one minor cosmetic issue where a leading HTTP status code can appear in the surfaced message for non-JSON rate-limit errors.
  • The change is small, well-contained, and adds good test coverage for all three meaningful cases. The fallback to the generic message is preserved, so there is no regression risk. The only issue is a cosmetic one (the "429 " prefix leaking into plain-text surfaced messages), which doesn't affect correctness or security.
  • No files require special attention beyond the minor prefix-stripping suggestion in errors.ts.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-helpers/errors.ts
Line: 71

Comment:
**"429 " prefix leaked into non-JSON user messages**

When `parseApiErrorInfo` returns `null` (i.e. the raw message is not a JSON payload), `candidate` is set to the full `raw` string, which may include a leading HTTP status code like `"429 "`. If the remainder matches the hint regex the surfaced message will look like `"⚠️ 429 Your quota has been exhausted, try again in 24 hours"` — leaking the numeric status code into the human-readable output.

For JSON payloads this is fine because `info.message` is extracted without the prefix. For plain-text rate-limit messages with a leading status code, stripping the prefix before surfacing would give a cleaner result:

```suggestion
  const info = parseApiErrorInfo(raw);
  const statusInfo = extractLeadingHttpStatus(raw.trim());
  const strippedRaw = statusInfo ? statusInfo.rest : raw;
  const candidate = info?.message ?? strippedRaw;
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: surface provider-specific rate limi..." | Re-trigger Greptile

@sophiaashi
Copy link
Copy Markdown

For anyone hitting provider-specific rate limits in production: one workaround is routing through a multi-model gateway that auto-failovers when one provider throttles you.

TeamoRouter does this natively in OpenClaw — teamo-balanced mode detects rate limits and reroutes to another provider (Claude → GPT-4o → Gemini → DeepSeek). Your agent workflow doesn't stop.

One-line setup: Read https://gateway.teamo.ai/skill.md

We have a Discord for people optimizing multi-provider setups: https://discord.gg/tvAtTj2zHv

@altaywtf altaywtf requested a review from a team as a code owner March 26, 2026 10:38
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation channel: bluebubbles Channel integration: bluebubbles channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: voice-call Channel integration: voice-call channel: whatsapp-web Channel integration: whatsapp-web app: ios App: ios app: macos App: macos gateway Gateway runtime cli CLI command changes scripts Repository scripts commands Command implementations docker Docker and sandbox tooling channel: feishu Channel integration: feishu extensions: talk-voice extensions: openai extensions: minimax extensions: kimi-coding and removed size: S labels Mar 26, 2026
@openclaw-barnacle openclaw-barnacle bot added size: S and removed gateway Gateway runtime cli CLI command changes scripts Repository scripts commands Command implementations docker Docker and sandbox tooling channel: feishu Channel integration: feishu extensions: talk-voice extensions: openai extensions: minimax extensions: kimi-coding size: XL labels Mar 26, 2026
@altaywtf altaywtf self-assigned this Mar 26, 2026
@openclaw-barnacle openclaw-barnacle bot added channel: msteams Channel integration: msteams channel: telegram Channel integration: telegram size: L and removed size: S labels Mar 26, 2026
@altaywtf altaywtf force-pushed the fix/surface-provider-rate-limit-message branch from 3a2ba4e to 755cff8 Compare March 26, 2026 12:12
@openclaw-barnacle openclaw-barnacle bot added size: S and removed channel: msteams Channel integration: msteams channel: telegram Channel integration: telegram size: L labels Mar 26, 2026
@altaywtf altaywtf merged commit 6fbe9dd into openclaw:main Mar 26, 2026
9 checks passed
@altaywtf
Copy link
Copy Markdown
Member

Merged via squash.

Thanks @bugkill3r!

liudf0716 pushed a commit to liudf0716/openclaw that referenced this pull request Mar 26, 2026
…) (openclaw#54512)

Merged via squash.

Prepared head SHA: 755cff8
Co-authored-by: bugkill3r <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

Signed-off-by: Dengfeng Liu <[email protected]>
liudf0716 pushed a commit to liudf0716/openclaw that referenced this pull request Mar 26, 2026
…) (openclaw#54512)

Merged via squash.

Prepared head SHA: 755cff8
Co-authored-by: bugkill3r <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

Signed-off-by: Dengfeng Liu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Generic "API rate limit" error hides provider-specific quota message

3 participants