fix(bedrock): omit empty additionalModelRequestFields and system from Converse API payload (#29565)

Amazon Nova Pro (and other strict Bedrock models) return 400 Malformed input
request when additionalModelRequestFields: {} or system: [] are present in the
payload. Both fields are optional in CommonRequestObject (total=False) and must
be omitted rather than sent as empty structures.

Co-authored-by: shin-berri <shin-laptop@berri.ai>
Co-authored-by: yuneng-jiang <yuneng@berri.ai>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Roi 2026-06-08 15:02:22 +03:00 committed by GitHub
parent b93656f132
commit 1d6402a89a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 71 additions and 8 deletions

View file

@ -1649,12 +1649,14 @@ class AmazonConverseConfig(BaseConfig):
bedrock_tool_config["toolChoice"] = tool_choice_values
data: CommonRequestObject = {
"additionalModelRequestFields": additional_request_params,
"system": system_content_blocks,
"inferenceConfig": self._transform_inference_params(
inference_params=inference_params
),
}
if additional_request_params:
data["additionalModelRequestFields"] = additional_request_params
if system_content_blocks:
data["system"] = system_content_blocks
# Handle all config blocks
for config_name, config_class in self.get_config_blocks().items():

View file

@ -3059,8 +3059,6 @@ async def test_bedrock_max_completion_tokens(model: str):
assert request_body == {
"messages": [{"role": "user", "content": [{"text": "Hello!"}]}],
"additionalModelRequestFields": {},
"system": [],
"inferenceConfig": {"maxTokens": 10},
}

View file

@ -1467,11 +1467,10 @@ def test_transform_request_with_function_tool():
)
# Verify the structure
assert "additionalModelRequestFields" in request_data
additional_fields = request_data["additionalModelRequestFields"]
# Function tools are not computer use tools, so they don't get anthropic_beta —
# additionalModelRequestFields should be absent (not serialized as empty {})
assert "additionalModelRequestFields" not in request_data
# Function tools are not computer use tools, so they don't get anthropic_beta
# They are processed through the regular tool config
assert "toolConfig" in request_data
assert "tools" in request_data["toolConfig"]
assert len(request_data["toolConfig"]["tools"]) == 1

View file

@ -128,6 +128,70 @@ class TestBedrockFilesTransformation:
# Must have messages
assert "messages" in model_input
# Nova Pro rejects empty additionalModelRequestFields / system — they must be absent
assert (
"additionalModelRequestFields" not in model_input
), "Nova: empty additionalModelRequestFields must be omitted, not serialized as {}"
assert (
"system" not in model_input
), "Nova: empty system must be omitted, not serialized as []"
def test_nova_batch_jsonl_omits_empty_converse_fields(self):
"""
Regression test: Amazon Nova Pro returns 400 Malformed input request when
additionalModelRequestFields or system are present but empty in the Converse
API payload. The proxy must strip these keys when they carry no data.
"""
from litellm.llms.bedrock.files.transformation import BedrockFilesConfig
config = BedrockFilesConfig()
openai_jsonl_content = [
{
"custom_id": "req-0",
"method": "POST",
"url": "/v1/chat/completions",
"body": {
"model": "us.amazon.nova-pro-v1:0",
"messages": [
{
"role": "user",
"content": "What is 1 + 1? Answer with just the number.",
}
],
"max_tokens": 16,
},
}
]
result = config._transform_openai_jsonl_content_to_bedrock_jsonl_content(
openai_jsonl_content
)
assert len(result) == 1
model_input = result[0]["modelInput"]
assert (
"additionalModelRequestFields" not in model_input
or model_input["additionalModelRequestFields"]
), "additionalModelRequestFields must be absent or non-empty — Nova rejects {}"
assert (
"system" not in model_input or model_input["system"]
), "system must be absent or non-empty — Nova rejects []"
# Validate the exact shape AWS accepts
assert model_input == {
"messages": [
{
"role": "user",
"content": [
{"text": "What is 1 + 1? Answer with just the number."}
],
}
],
"inferenceConfig": {"maxTokens": 16},
}
def test_nova_image_content_uses_converse_image_blocks(self):
"""
Test that image_url content blocks are converted to Bedrock Converse