diff --git a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py index aaf357effa6..0e5b2952377 100644 --- a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py @@ -580,6 +580,8 @@ class AmazonAnthropicClaudeMessagesConfig( content = msg.get("content") if isinstance(content, str): if content: + if content.startswith("x-anthropic-billing-header:"): + continue block = {"type": "text", "text": content} if "cache_control" in msg: block["cache_control"] = msg["cache_control"] @@ -590,6 +592,10 @@ class AmazonAnthropicClaudeMessagesConfig( if item.get("type") == "text": text_val = item.get("text") if text_val: + if text_val.startswith( + "x-anthropic-billing-header:" + ): + continue block = {"type": "text", "text": text_val} if "cache_control" in item: block["cache_control"] = item["cache_control"] diff --git a/tests/test_litellm/llms/bedrock/messages/invoke_transformations/test_anthropic_claude3_transformation.py b/tests/test_litellm/llms/bedrock/messages/invoke_transformations/test_anthropic_claude3_transformation.py index 6bfd656568a..2840bf27b3f 100644 --- a/tests/test_litellm/llms/bedrock/messages/invoke_transformations/test_anthropic_claude3_transformation.py +++ b/tests/test_litellm/llms/bedrock/messages/invoke_transformations/test_anthropic_claude3_transformation.py @@ -1868,3 +1868,40 @@ def test_bedrock_anthropic_messages_system_role_transformation(): {"content": "no_role_key"}, {"role": "user", "content": "Hello"}, ] + + # 11. Test case: system message in messages array containing billing-header as string (should be skipped) + req = config.transform_anthropic_messages_request( + model="bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0", + messages=[ + {"role": "system", "content": "x-anthropic-billing-header:some-billing-id"}, + {"role": "user", "content": "Hello"}, + ], + anthropic_messages_optional_request_params={"max_tokens": 100}, + litellm_params={}, + headers={}, + ) + assert req["messages"] == [{"role": "user", "content": "Hello"}] + assert "system" not in req + + # 12. Test case: system message in messages array containing billing-header inside list (should be skipped) + req = config.transform_anthropic_messages_request( + model="bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0", + messages=[ + { + "role": "system", + "content": [ + { + "type": "text", + "text": "x-anthropic-billing-header:some-billing-id", + }, + {"type": "text", "text": "Valid system prompt"}, + ], + }, + {"role": "user", "content": "Hello"}, + ], + anthropic_messages_optional_request_params={"max_tokens": 100}, + litellm_params={}, + headers={}, + ) + assert req["messages"] == [{"role": "user", "content": "Hello"}] + assert req["system"] == [{"type": "text", "text": "Valid system prompt"}]