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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions