Skip to content

429 errors are not differentiated by error type #405

@zikajk

Description

@zikajk

ECA classifies all HTTP 429 responses as :rate-limited and retries them up to 10 times with exponential backoff. But providers use 429 for fundamentally different errors — e.g. OpenAI returns 429 for both rate_limit_exceeded (transient) and usage_limit_reached (billing/quota, not transient).

Example: OpenAI returns 429 {"error":{"type":"usage_limit_reached","message":"The usage limit has been reached","resets_in_seconds":7139}}. ECA shows "Rate limited" and retries 10 times, wasting minutes on an error that resets in ~2 hours.

What would be nice to change

  1. New non-retryable error type (e.g. :billing) for quota/billing errors
  2. Body patterns to detect them: usage_limit_reached, insufficient_quota, billing_hard_limit_reached, etc.
  3. 429 classifier branch must check body before falling back to :rate-limited
  4. Same patterns in classify-by-message (fallback for SSE/exception errors)
  5. UI label — show "Usage limit reached" instead of "Rate limited"
  6. Nice-to-have: if the provider includes reset info (e.g. resets_in_seconds), surface it to the user

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions