Request Options, Errors, and Retries

Purpose and Scope

Use this page when a Claude SDK request behaves differently than expected: a custom header is not present, a response needs its request identifier, a generated URL rejects a path parameter, a middleware changes the request, or a streaming fallback path needs to be inspected. The SDK exposes resource methods for day-to-day work, but request-level troubleshooting usually crosses the client, shared core modules, and regression tests. The goal is to help you map a symptom to the right layer before changing application code or opening an issue.

Sources: src/client.ts, src/core/README.md, tests/responses.test.ts

The official API error guidance describes Anthropic errors as non-success status responses with a request identifier header and a JSON error object containing a type and message. In practice, that means production runbooks should capture the request identifier, classify failures by error type or status, and avoid depending on exact message text. The TypeScript SDK tests reinforce the same operational habit by checking how response helpers expose the request identifier for object responses and explicit response envelopes.

Sources: tests/responses.test.ts

Relevant Source Files

  • src/client.ts — Primary client implementation for request construction, client options, and request execution behavior.
  • src/core/README.md — States that the core directory contains public, non-resource-specific SDK functionality.
  • tests/middleware.test.ts — Regression coverage for non-streaming middleware behavior and request pipeline expectations.
  • tests/middleware-streaming.test.ts — Regression coverage for streaming middleware behavior, fallback streams, and direct middleware driving.
  • tests/responses.test.ts — Regression coverage for response envelopes, request identifiers, object responses, arrays, pages, strings, and promise typing.
  • tests/path.test.ts — Regression coverage for generated path template handling, escaping, invalid segments, and cross-realm values.
  • tests/buildHeaders.test.ts — Regression coverage for header normalization, null removal semantics, cookie joining, and append-style headers.

System-to-Code Mapping

The public client is the entry point for most request options. Tests instantiate the client with an API key and a custom fetch implementation, then call a Messages resource method to verify how response metadata is returned. That pattern is useful for debugging because it isolates network behavior: replace the transport with a controlled fetch, return a synthetic response, and verify whether the SDK, your middleware, or the remote API is responsible for the observed result. The core README frames this kind of logic as non-resource-specific SDK functionality rather than Messages-only behavior.

Sources: src/client.ts, src/core/README.md, tests/responses.test.ts

Response handling is centered on the API promise abstraction and its helpers. The response tests verify that awaiting an object response can attach a request identifier while preserving normal JSON serialization, that using the response envelope returns the parsed data, raw response, and request identifier together, and that arrays and paginated pages do not receive the same attached metadata shape. This distinction matters when logging. If your code needs the response headers reliably, prefer the explicit envelope form rather than assuming every returned value can carry extra metadata.

Sources: tests/responses.test.ts

Execution Flow for a Debug Session

Start by reproducing the request with the smallest possible client configuration. If the issue is transport-related, pass a custom fetch function so you can record the outgoing request and return a known response. Next, switch the resource call to the envelope helper and log the request identifier and response headers. If the server returns a non-success status, keep the request identifier with the error report, because official Anthropic guidance asks users to include that value when escalating. This sequence separates client configuration, transport, server response, and application parsing.

Sources: src/client.ts, tests/responses.test.ts

Then inspect the request shape. Header bugs often come from casing, duplicate names, null values, or list joining. The header tests show that header names are normalized case-insensitively, undefined values do not erase an earlier value, null explicitly marks a header as removed, and cookie values are joined with semicolons rather than commas. The same tests cover an append-style helper header where duplicate values are deduplicated and comma-joined unless a later null removes the header. This is important when combining defaults, per-request overrides, and middleware-provided headers.

Sources: tests/buildHeaders.test.ts

Finally, validate path parameters before assuming the API endpoint is wrong. The path tests exercise a template tag that rejects null, undefined, plain objects, unsafe dot segments, and encoded dot variants that would make a URL ambiguous. They also cover valid primitive-like values, custom string conversion, and cross-realm objects from environments such as Jest or browser frames. A surprising path error is usually a safety check, not a server rejection. Convert identifiers to safe strings before interpolation and avoid passing objects that stringify accidentally.

Sources: tests/path.test.ts

Middleware and Streaming Behavior

Middleware troubleshooting has two modes: ordinary request pipeline behavior and stream-aware behavior. The streaming middleware tests drive middleware directly by passing a queued sequence of responses and collecting the resulting output stream. The fixture comments describe a primary stream that emits thinking and partial text, then stops with a refusal and a fallback credit token, followed by a fallback stream that completes the message. That test design shows what to inspect when a streamed response appears spliced, retried, or replaced by fallback output.

Sources: tests/middleware.test.ts, tests/middleware-streaming.test.ts

For streaming problems, preserve the wire format in your reproduction. The tests build server-sent event frames, use text event streams, and include synthetic cases where server tool use emits incremental input JSON before the refusal terminal arrives in the middle of a tool loop. Those details are valuable because stream middleware cannot be debugged by looking only at the final message. Capture event order, terminal deltas, fallback state, and whether the next middleware call received the expected request body. Abort handling and partial output cleanup should be verified with the same event-level care.

Sources: tests/middleware-streaming.test.ts

Compact Reference

ConcernWhat to checkSource signal
Response metadataUse the response envelope when you need headers and the request identifier together.tests/responses.test.ts
Object responsesParsed objects can expose a request identifier while preserving ordinary JSON serialization.tests/responses.test.ts
Arrays and pagesDo not assume array or page values carry attached request metadata.tests/responses.test.ts
Header overridesUndefined leaves previous values alone; null removes a header.tests/buildHeaders.test.ts
Duplicate cookiesCookie values are joined with semicolons.tests/buildHeaders.test.ts
Helper headersAppend-style helper headers are comma-joined and deduplicated.tests/buildHeaders.test.ts
Path parametersUnsafe dot segments, nullish values, and arbitrary objects are rejected.tests/path.test.ts
Streaming middlewareReproduce event order and fallback state, not only the final text.tests/middleware-streaming.test.ts

Next Steps

If the failure is an API rejection, classify it by status and error type, keep the request identifier, and compare the request body against the relevant resource reference page. If the failure is local, choose the narrowest test family above and reproduce that behavior with a custom fetch or direct middleware driver. For higher-level usage, read the Messages, Streaming Responses, and Authentication and Client Configuration pages before changing retry policy, headers, or middleware in a production integration.