fix: add universal billing error detection for router mode

- Add HTTP 402 and 'insufficient credits' patterns to error classification
- Detect provider billing errors in both exception and message content paths
This commit is contained in:
ajmallesh
2026-01-16 11:18:27 -08:00
parent f4e2b49493
commit 5428422b6c
2 changed files with 5 additions and 0 deletions

View File

@@ -60,12 +60,15 @@ export function detectApiError(content: string): ApiErrorDetection {
// When Claude Code hits its spending cap, it returns a short message like // When Claude Code hits its spending cap, it returns a short message like
// "Spending cap reached resets 8am" instead of throwing an error. // "Spending cap reached resets 8am" instead of throwing an error.
// These should retry with 5-30 min backoff so workflows can recover when cap resets. // These should retry with 5-30 min backoff so workflows can recover when cap resets.
// Also catches provider billing errors (OpenRouter 402, etc.) that appear in message content.
const BILLING_PATTERNS = [ const BILLING_PATTERNS = [
'spending cap', 'spending cap',
'spending limit', 'spending limit',
'cap reached', 'cap reached',
'budget exceeded', 'budget exceeded',
'usage limit', 'usage limit',
'402', // HTTP Payment Required (universal)
'insufficient credits', // OpenRouter
]; ];
const isBillingError = BILLING_PATTERNS.some((pattern) => const isBillingError = BILLING_PATTERNS.some((pattern) =>

View File

@@ -211,7 +211,9 @@ export function classifyErrorForTemporal(error: unknown): TemporalErrorClassific
// === BILLING ERRORS (Retryable with long backoff) === // === BILLING ERRORS (Retryable with long backoff) ===
// Anthropic returns billing as 400 invalid_request_error // Anthropic returns billing as 400 invalid_request_error
// Human can add credits OR wait for spending cap to reset (5-30 min backoff) // Human can add credits OR wait for spending cap to reset (5-30 min backoff)
// 402 is HTTP "Payment Required" - universal across providers (OpenRouter, etc.)
if ( if (
message.includes('402') ||
message.includes('billing_error') || message.includes('billing_error') ||
message.includes('credit balance is too low') || message.includes('credit balance is too low') ||
message.includes('insufficient credits') || message.includes('insufficient credits') ||