From a0cef91f0b355e659c3a11756f344d070f2324ae Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Wed, 30 Sep 2026 18:50:14 -0700 Subject: [PATCH] fix(bedrock): forward a non-string reasoning_effort on the native route instead of crashing A list or dict reasoning_effort hit a frozenset membership test in without_refused_reasoning_effort and raised TypeError, which the proxy surfaced as a 500 APIConnectionError with no upstream call. The value is now left alone unless it is a string Bedrock's native endpoint refuses, so AWS answers the malformed value with its own 400 like it does for an int --- .../bedrock/chat/chat_completions/transformation.py | 3 ++- .../test_bedrock_chat_completions_transformation.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/litellm/llms/bedrock/chat/chat_completions/transformation.py b/litellm/llms/bedrock/chat/chat_completions/transformation.py index 1477a46dcad..ac1d2cf2498 100644 --- a/litellm/llms/bedrock/chat/chat_completions/transformation.py +++ b/litellm/llms/bedrock/chat/chat_completions/transformation.py @@ -108,7 +108,8 @@ def chat_completions_reasoning_efforts_refused_for(model: str) -> frozenset[str] def without_refused_reasoning_effort(model: str, params: Mapping[str, object]) -> Mapping[str, object]: - if params.get("reasoning_effort") not in chat_completions_reasoning_efforts_refused_for(model): + effort: Final = params.get("reasoning_effort") + if not isinstance(effort, str) or effort not in chat_completions_reasoning_efforts_refused_for(model): return params return _without_params(params, frozenset(("reasoning_effort",))) diff --git a/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py b/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py index 5ea3c8c31bd..db1efd49cb9 100644 --- a/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py +++ b/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py @@ -573,6 +573,19 @@ def test_map_openai_params_keeps_reasoning_effort_low_for_grok(): assert mapped["reasoning_effort"] == "low" +@pytest.mark.parametrize("model", ["us.xai.grok-4.6", "global.openai.gpt-5.6-sol"]) +@pytest.mark.parametrize("reasoning_effort", [["low"], {"effort": "low"}, 5]) +def test_map_openai_params_forwards_a_malformed_reasoning_effort_for_aws_to_refuse(model, reasoning_effort): + cfg = AmazonBedrockRuntimeChatCompletionsConfig() + mapped = cfg.map_openai_params( + non_default_params={"reasoning_effort": reasoning_effort, "max_tokens": 64}, + optional_params={}, + model=model, + drop_params=False, + ) + assert mapped["reasoning_effort"] == reasoning_effort + + def test_map_openai_params_keeps_reasoning_effort_none_for_gpt56(): cfg = AmazonBedrockRuntimeChatCompletionsConfig() mapped = cfg.map_openai_params(