#15109: fix: distinguish transient API errors from billing errors
agents
stale
size: XS
Cluster:
Error Handling Improvements
Fixes #15055
## Summary
Fix error message handling to distinguish between transient API failures (rate limits, timeouts) and actual billing issues.
## Problem
Previously, all API failures showed the same billing error message, making it impossible for users to distinguish between:
- Genuine billing issues (insufficient credits)
- Temporary errors (rate limiting, timeouts)
## Changes
- Check `isRateLimitErrorMessage()` before `isBillingErrorMessage()`
- Check `isTimeoutErrorMessage()` before `isBillingErrorMessage()`
- Add tests for rate limit (429) and timeout error handling
- Ensure transient errors show appropriate retry messages
## Test Results
- ✅ All existing tests pass (16/16 in formatassistanterrortext.test.ts)
- ✅ New tests added for rate limit and timeout scenarios
- ✅ Full test suite: 6235 tests passed
## AI-Assisted Development
This PR was developed with assistance from Claude Opus 4.6. The code has been reviewed and tested to ensure correctness.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates `formatAssistantErrorText` to classify rate-limit and timeout errors before billing errors, and adds tests to ensure transient errors don’t display the billing/credits messaging.
Within the wider codebase, assistant text is also passed through `sanitizeUserFacingText(..., { errorContext: true })` in multiple user-facing pipelines (assistant text extraction and reply normalization). That sanitizer still collapses rate-limit errors into the generic “temporarily overloaded” message in its `ERROR_PREFIX_RE` rewrite path, which can negate the PR’s goal on those surfaces.
<h3>Confidence Score: 4/5</h3>
- Mostly safe to merge, but there is one remaining user-facing classification inconsistency for rate limits.
- The change to `formatAssistantErrorText` is small and well-covered by targeted tests, but another sanitizer used in user-facing flows still rewrites rate-limit errors to the overloaded message, which conflicts with the stated behavior change and can cause incorrect messaging in some surfaces.
- src/agents/pi-embedded-helpers/errors.ts
<sub>Last reviewed commit: 7e1df79</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#8661: fix: display rate limit errors correctly instead of as context over...
by dbottme · 2026-02-04
87.9%
#9173: Fix: Improve error messaging for API rate limits and billing errors
by vishaltandale00 · 2026-02-04
87.7%
#19271: fix: remove false-positive billing text rewrite in sanitizeUserFaci...
by MisterGuy420 · 2026-02-17
81.9%
#12273: fix: prevent billing error false positive on bare '402' in chat con...
by Yida-Dev · 2026-02-09
81.6%
#16307: fix: surface billing/auth FailoverErrors as user-friendly messages
by petter-b · 2026-02-14
81.5%
#13318: fix(agents): prevent sanitizeUserFacingText from rewriting conversa...
by hleliofficiel · 2026-02-10
80.7%
#19451: fix(errors): surface provider hint for role-ordering failures
by rafaelipuente · 2026-02-17
79.3%
#23520: fix: trigger failover on Anthropic insufficient_quota (HTTP 400) (#...
by dissaozw · 2026-02-22
79.3%
#13658: fix: silent model failover with fallback notification
by taw0002 · 2026-02-10
78.0%
#14368: fix: skip auth profile cooldown on format errors to prevent provide...
by koatora20 · 2026-02-12
77.9%