Ecosystem

anthropic-sdk-python 2.5.0: error_code, details, and One Class per Error

3 min read AI-generated

The new error table has 88 entries: 16 keyed on the HTTP status alone, 72 on named error codes like enforced_spend_limit_reached.

Featured image for "anthropic-sdk-python 2.5.0: error_code, details, and One Class per Error"

Anthropic shipped new SDK versions on Tuesday evening: anthropic-sdk-python 2.5.0, plus sdk-v1.5.0, vertex-sdk-v1.1.2 and google-cloud-sdk-v1.1.3 for TypeScript. None of it is in the Claude Platform release notes yet; the newest entry there is dated November 3.

The core is the same in both languages. The API now returns structured error details, and the SDK turns them into exception classes you can catch by name.

Four new fields on APIStatusError

In Python, APIStatusError now carries api_message (the error.message from the response body), type (error.type), error_code (error.details.error_code when it’s a string) and details as a typed object built from error.details. In TypeScript the fields are apiMessage, errorCode and details, and they sit on APIError.

Alongside that comes a new file, _error_classes.py, holding a lookup table. It has 88 entries. 16 of them key on the HTTP status alone, so 400 becomes BadRequestError, 429 RateLimitError, 529 OverloadedError. The other 72 key on a pair of status and error code: (429, "enforced_spend_limit_reached") becomes EnforcedSpendLimitReachedError, (404, "thread_not_found") becomes ThreadNotFoundError, (400, "claude_code_version_too_old") becomes ClaudeCodeVersionTooOldError. With no matching code, the SDK falls back to the status, and anything from 500 up lands on InternalServerError.

The list reads like a table of contents for the past few months. thread_not_found, thread_already_continued and thread_fingerprint_mismatch belong to message threads in the Messages API. storage_quota_exceeded, skill_name_taken, plugin_name_taken and scan_pending come out of skills and plugins. Nine codes cover compaction, eight cover CMEK keys, and a dozen or so cover organization and workspace management.

Plus two bits of path hardening

Both SDKs now reject path parameters like ;x, .;x and ..;x. In the Vertex SDK, the project ID, region and model name are percent-encoded in the request path, so a slash in the model name can’t push the request outside /publishers/anthropic/models/; an empty model name, or a value of . or .., throws an AnthropicError. Bedrock gets the same treatment, raising a ValueError for . or ... In the Google Cloud SDK, project, location and workspace ID are encoded in the derived base URL.

Smaller fixes: OverloadedError and ServiceUnavailableError are now subclasses of InternalServerError, the first parse of each response is thread-safe, unions validate correctly across threads, and the memory tool can no longer rename or delete the /memories directory. Server-sent events are decoded once per chunk instead of repeatedly. There’s also a new ids filter for listing workspaces.

Parsing error strings was always the wrong fix

Anyone running an app on the Claude API knows the spot: a 400 comes back, and somewhere in the code sits an if "spend limit" in str(e). Lines like that break the moment somebody at Anthropic rewords a message. error_code gives you a stable key for it, and with 72 classes you don’t even have to compare it yourself — except EnforcedSpendLimitReachedError does the job.

That the codes line up with last week’s Admin API expansion is no accident. If you manage spend limits and RBAC through the API, you hit errors your own user didn’t cause and that need different handling. For me this is one of the more useful changes since API version 2026-10-21: unglamorous, but it deletes a whole category of error-handling hacks.

Sources

Claude PlatformSDKAPIDeveloper Tools