mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
Fix: Skip empty text blocks in Anthropic system messages (#17442)
When translating system messages for the Anthropic API, empty text content blocks cause the error "messages: text content blocks must be non-empty". This fix skips empty string content and empty text blocks in list content to prevent this error. Fixes issue with Vertex AI Anthropic API calls. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a6ce118989
commit
06d42fbd30
2 changed files with 94 additions and 2 deletions
|
|
@ -786,6 +786,9 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
valid_content: bool = False
|
||||
system_message_block = ChatCompletionSystemMessage(**message)
|
||||
if isinstance(system_message_block["content"], str):
|
||||
# Skip empty text blocks - Anthropic API raises errors for empty text
|
||||
if not system_message_block["content"]:
|
||||
continue
|
||||
anthropic_system_message_content = AnthropicSystemMessageContent(
|
||||
type="text",
|
||||
text=system_message_block["content"],
|
||||
|
|
@ -800,10 +803,14 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
valid_content = True
|
||||
elif isinstance(message["content"], list):
|
||||
for _content in message["content"]:
|
||||
# Skip empty text blocks - Anthropic API raises errors for empty text
|
||||
text_value = _content.get("text")
|
||||
if _content.get("type") == "text" and not text_value:
|
||||
continue
|
||||
anthropic_system_message_content = (
|
||||
AnthropicSystemMessageContent(
|
||||
type=_content.get("type"),
|
||||
text=_content.get("text"),
|
||||
text=text_value,
|
||||
)
|
||||
)
|
||||
if "cache_control" in _content:
|
||||
|
|
|
|||
|
|
@ -1290,10 +1290,95 @@ def test_effort_with_other_features():
|
|||
litellm_params={},
|
||||
headers={}
|
||||
)
|
||||
|
||||
|
||||
# Verify all features are present
|
||||
assert "output_config" in result
|
||||
assert result["output_config"]["effort"] == "low"
|
||||
assert "tools" in result
|
||||
assert len(result["tools"]) > 0
|
||||
assert "thinking" in result
|
||||
|
||||
|
||||
def test_translate_system_message_skips_empty_string_content():
|
||||
"""
|
||||
Test that translate_system_message skips system messages with empty string content.
|
||||
|
||||
Fixes: Vertex AI Anthropic API error "messages: text content blocks must be non-empty"
|
||||
"""
|
||||
config = AnthropicConfig()
|
||||
|
||||
# Test empty string content - should not produce any anthropic system message content
|
||||
messages = [
|
||||
{"role": "system", "content": ""},
|
||||
{"role": "user", "content": "Hello"},
|
||||
]
|
||||
|
||||
result = config.translate_system_message(messages)
|
||||
|
||||
# Empty system message should produce no anthropic content blocks
|
||||
assert len(result) == 0
|
||||
|
||||
|
||||
def test_translate_system_message_skips_empty_list_content():
|
||||
"""
|
||||
Test that translate_system_message skips empty text blocks in list content.
|
||||
|
||||
Fixes: Vertex AI Anthropic API error "messages: text content blocks must be non-empty"
|
||||
"""
|
||||
config = AnthropicConfig()
|
||||
|
||||
# Test list content with empty text block
|
||||
messages = [
|
||||
{"role": "system", "content": [
|
||||
{"type": "text", "text": ""},
|
||||
{"type": "text", "text": "Valid content"},
|
||||
{"type": "text", "text": ""},
|
||||
]},
|
||||
{"role": "user", "content": "Hello"},
|
||||
]
|
||||
|
||||
result = config.translate_system_message(messages)
|
||||
|
||||
# Only non-empty text blocks should be included
|
||||
assert len(result) == 1
|
||||
assert result[0]["text"] == "Valid content"
|
||||
|
||||
|
||||
def test_translate_system_message_preserves_valid_content():
|
||||
"""
|
||||
Test that translate_system_message preserves valid system message content.
|
||||
"""
|
||||
config = AnthropicConfig()
|
||||
|
||||
# Test valid string content
|
||||
messages = [
|
||||
{"role": "system", "content": "You are a helpful assistant."},
|
||||
{"role": "user", "content": "Hello"},
|
||||
]
|
||||
|
||||
result = config.translate_system_message(messages)
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0]["type"] == "text"
|
||||
assert result[0]["text"] == "You are a helpful assistant."
|
||||
|
||||
|
||||
def test_translate_system_message_preserves_cache_control():
|
||||
"""
|
||||
Test that translate_system_message preserves cache_control on valid content.
|
||||
"""
|
||||
config = AnthropicConfig()
|
||||
|
||||
# Test list content with cache_control
|
||||
messages = [
|
||||
{"role": "system", "content": [
|
||||
{"type": "text", "text": "Cached content", "cache_control": {"type": "ephemeral"}},
|
||||
]},
|
||||
{"role": "user", "content": "Hello"},
|
||||
]
|
||||
|
||||
result = config.translate_system_message(messages)
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0]["text"] == "Cached content"
|
||||
assert result[0]["cache_control"] == {"type": "ephemeral"}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue