Skip to content

docs/rate-limits.mdx claims SDKs auto-retry 429s with exponential backoff — both SDKs explicitly exclude HTTP error responses from retry #1910

Description

@realfishsam

Gap

docs/rate-limits.mdx states: "When you hit a limit, the API returns 429 Too Many Requests... The SDKs handle short bursts automatically with exponential backoff." In reality, both SDKs' retry logic is explicitly scoped to transport-level failures only and never retries on any HTTP error response, including 429 — a caller hitting a rate limit gets an immediate unhandled RateLimitExceeded exception, not a transparent retry.

Core

N/A — this is an SDK-layer (HTTP client) behavior, not a core exchange method.

TypeScript SDK

sdks/typescript/pmxt/client.ts:551-586 (fetchWithRetry) — its own doc comment states: "Only retries on connection-level errors (ECONNREFUSED, ECONNRESET) — never on HTTP responses (4xx, 5xx)." The catch block only fires on a thrown fetch() exception (network failure); a resolved Response with status 429 is returned normally and propagates straight to error parsing / RateLimitExceeded, never entering the retry path.

Python SDK

sdks/python/pmxt/client.py:496-522 (_fetch_with_retry) — same pattern, doc comment: "Only retries on connection-level errors... never on HTTP/API errors (4xx, 5xx)." Its except ApiException: raise # HTTP errors are not retryable here explicitly re-raises immediately on any HTTP error, including 429.

Further evidence that no automatic backoff exists: RateLimitExceeded/retryAfter (sdks/typescript/pmxt/errors.ts:75-80,158-159) and retry_after (sdks/python/pmxt/errors.py:89-91,165) are stored purely as metadata on the raised exception for the caller to act on manually — nothing in either SDK consumes that field to actually retry.

Evidence

Direct read of both retry implementations and their own inline documentation, which explicitly disclaim HTTP-error retries; grep for any consumer of retryAfter/retry_after that triggers a retry loop found none in either SDK.

Impact

Code written to trust the documented behavior ("SDKs handle short bursts automatically") will get an unhandled RateLimitExceeded exception on the very first 429 response instead of the promised transparent backoff-and-retry, directly contradicting docs/rate-limits.mdx.


Found by automated Core-to-SDK surface coverage audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2: mediumbugSomething isn't workingcore-sdk-gapCore engine capabilities not exposed in SDKsdocumentationImprovements or additions to documentationeffort: small

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions