feat(anthropic): retry /v1/messages after invalid thinking signature - #25674
Merged
ishaan-berri merged 3 commits intoApr 14, 2026
Merged
Conversation
Strip thinking blocks from the request body and retry once when Anthropic returns an invalid thinking signature error (e.g. after credential or deployment change). Applies to all BaseAnthropicMessagesConfig providers (direct Anthropic, Bedrock, Vertex, Azure AI). Made-with: Cursor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Contributor
Greptile SummaryThis PR adds a self-healing retry mechanism for the Anthropic Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| litellm/llms/anthropic/common_utils.py | Adds three helpers: error detector, message stripper (correctly drops messages that become empty after stripping), and request dict mutator. Logic is sound; the message-drop behavior when ALL messages contain only thinking blocks is documented but can leave messages: []. |
| litellm/llms/base_llm/anthropic_messages/transformation.py | Adds three hook methods to BaseAnthropicMessagesConfig: max attempts property (2), status-code-guarded should_retry, and transform_anthropic_messages_request_on_http_error. The transform method redundantly re-checks the error type that should_retry already confirmed. |
| litellm/llms/custom_httpx/llm_http_handler.py | Extracts the HTTP POST into a new private retry helper _async_post_anthropic_messages_with_http_error_retry. Loop structure, error handling, re-signing on retry, and the unreachable sentinel RuntimeError are all correct. Two identical dict(litellm_params) copies are created unnecessarily. |
| tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py | Six new pure-mock unit tests covering the detector, stripper, and config hooks — no real network calls. Tests confirm the messages == [] edge case but don't cover the retry loop itself or the consecutive same-role message scenario. |
Sequence Diagram
sequenceDiagram
participant Caller as async_anthropic_messages_handler
participant Retry as _async_post_anthropic_messages_with_http_error_retry
participant HTTP as AsyncHTTPHandler
participant Config as BaseAnthropicMessagesConfig
Caller->>Retry: POST /v1/messages (with thinking blocks + signed body)
Retry->>HTTP: post(url, headers, signed_json_body or json body, stream)
HTTP-->>Retry: 400 HTTPStatusError (invalid thinking signature)
Retry->>Config: should_retry_anthropic_messages_on_http_error(e, litellm_params)
Config-->>Retry: "True (status==400 and error matches)"
Retry->>Config: transform_anthropic_messages_request_on_http_error(e, request_body)
Note over Config: strips thinking/redacted_thinking blocks<br/>removes top-level "thinking" param
Config-->>Retry: mutated request_body
Retry->>Config: sign_request(headers, optional_params, request_body, ...)
Config-->>Retry: new headers + signed_json_body
Retry->>HTTP: post(url, new_headers, new_signed_body, stream)
HTTP-->>Retry: 200 OK response
Retry-->>Caller: httpx.Response
Reviews (2): Last reviewed commit: "fix(anthropic): tighten thinking-signatu..." | Re-trigger Greptile
- Omit messages whose list content is empty after stripping thinking blocks - Retry only on HTTP 400 plus invalid-signature body match - Return response inline from retry loop; drop unreachable None guard - Tests: thinking-only turn dropped, non-400 no retry Made-with: Cursor
Sameerlite
temporarily deployed
to
integration-postgres
April 14, 2026 04:33 — with
GitHub Actions
Inactive
Sameerlite
temporarily deployed
to
integration-postgres
April 14, 2026 04:33 — with
GitHub Actions
Inactive
Sameerlite
temporarily deployed
to
integration-postgres
April 14, 2026 04:33 — with
GitHub Actions
Inactive
Sameerlite
had a problem deploying
to
integration-postgres
April 14, 2026 04:33 — with
GitHub Actions
Error
ishaan-berri
merged commit Apr 14, 2026
693c846
into
litellm_ishaan_april14
101 of 108 checks passed
ishaan-berri
deleted the
litellm_anthropic-messages-thinking-signature-retry
branch
April 14, 2026 17:10
fzowl
pushed a commit
to fzowl/litellm
that referenced
this pull request
Jun 24, 2026
…ges-thinking-signature-retry feat(anthropic): retry /v1/messages after invalid thinking signature
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When Anthropic returns an invalid encrypted thinking
signatureerror (common after switching API keys, model deployment, or provider), LiteLLM now stripsthinking/redacted_thinkingblocks and the top-levelthinkingparam from the outbound Messages API body and retries the HTTP request once.Implementation
common_utils.py: detect the error shape and strip thinking content from the request dict.BaseAnthropicMessagesConfig: hooks for max attempts, should-retry, and transform (lazy imports avoid circular imports).async_anthropic_messages_handler: retry loop with re-sign_requestfor Bedrock.Coverage
Applies to any provider using
BaseAnthropicMessagesConfig(direct Anthropic, Bedrock Claude messages invoke path, Vertex partner Claude, Azure AI Anthropic).Tests
tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py::TestAnthropicThinkingSignatureSelfHeal