fix: strip empty text content blocks in /v1/messages endpoint - #23097
Conversation
Claude's API returns assistant messages with empty text blocks
({"type": "text", "text": ""}) alongside tool_use blocks during
multi-turn tool-use conversations. These blocks are rejected when
sent back to the API with "text content blocks must be non-empty".
Sanitization already exists for other code paths (/v1/chat/completions
for both Anthropic and Bedrock), but NOT for the /v1/messages native
path. This adds the same treatment by stripping empty text blocks
from messages in async_anthropic_messages_handler before they are
forwarded to the provider.
Fixes BerriAI#22930
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
|
Greptile SummaryThis PR fixes a The fix adds a module-level Key strengths:
Confidence Score: 5/5
Sequence DiagramsequenceDiagram
participant Client as Anthropic SDK Client
participant LiteLLM as LiteLLM /v1/messages
participant Sanitizer as _sanitize_anthropic_messages_empty_text_blocks()
participant Transform as transform_anthropic_messages_request()
participant API as Upstream Provider (Anthropic / Bedrock / Vertex / Azure)
Client->>LiteLLM: POST /v1/messages (messages with empty text blocks)
Note over LiteLLM: async_anthropic_messages_handler()
LiteLLM->>Sanitizer: messages (may contain {"type":"text","text":""})
Sanitizer-->>LiteLLM: sanitized messages (empty text blocks stripped)
LiteLLM->>Transform: sanitized messages
Transform-->>LiteLLM: request_body
LiteLLM->>API: POST (clean request body, no empty text blocks)
API-->>LiteLLM: 200 OK (no 400 invalid_request_error)
LiteLLM-->>Client: response
Last reviewed commit: 61e7ebb |
| Ref: https://github.com/BerriAI/litellm/issues/22930 | ||
| """ | ||
|
|
||
| import pytest |
There was a problem hiding this comment.
pytest is imported but never used. All test assertions use plain assert statements—no pytest.raises(), pytest.mark, or other pytest APIs are referenced. This unused import should be removed to prevent linting warnings.
| import pytest |
|
I have read the CLA Document and I hereby sign the CLA |
…I#23097) Claude's API returns assistant messages with empty text blocks ({"type": "text", "text": ""}) alongside tool_use blocks during multi-turn tool-use conversations. These blocks are rejected when sent back to the API with "text content blocks must be non-empty". Sanitization already exists for other code paths (/v1/chat/completions for both Anthropic and Bedrock), but NOT for the /v1/messages native path. This adds the same treatment by stripping empty text blocks from messages in async_anthropic_messages_handler before they are forwarded to the provider. Fixes BerriAI#22930
…BerriAI#23097)" This reverts commit 2c738cc.
…BerriAI#23097)" This reverts commit 2c738cc.
Summary
Fixes #22930
When routing Anthropic SDK requests through LiteLLM's
/v1/messagesendpoint, multi-turn tool-use conversations fail because Claude's API returns assistant messages with empty text blocks ({"type": "text", "text": ""}) alongsidetool_useblocks. These empty blocks are forwarded as-is and rejected when sent back with:Sanitization already exists for other code paths:
/v1/chat/completions— [Bug]: Bedrock throws 400 on empty content #7169, PR Fix bedrock empty content error #7177/v1/chat/completions— [Bug]: Empty text content blocks not sanitized for databricks/ provider (already fixed for bedrock and anthropic) #20370modify_params=Trueinanthropic_messages_pt— [Bug] Anthropic Protocol Violation: "unexpected tool_use_id" & "empty text content" (Fix Included) #19061, PR Litellm sanitise anthropic mesages 2 #21464But none of these fixes cover the
/v1/messagesnative path, which passes messages throughasync_anthropic_messages_handler→transform_anthropic_messages_requestwithout any sanitization.Changes
_sanitize_anthropic_messages_empty_text_blocks()helper inlitellm/llms/custom_httpx/llm_http_handler.pythat strips empty/whitespace-only text blocks from Anthropic-format message content arrays before forwardingasync_anthropic_messages_handler()right beforetransform_anthropic_messages_request(), so all providers using the native/v1/messagespath benefit (Anthropic direct, Bedrock invoke, Azure AI, Vertex AI){"type": "text", "text": "..."}placeholderTest plan
tests/test_litellm/llms/anthropic/test_v1_messages_empty_text_sanitization.pywith 10 unit tests covering: