From 06b44105e8ced3762d436f2396f2b1020c060c10 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:32:50 +0000 Subject: [PATCH] fix(bedrock/claude_platform): warn when claude_platform_unsupported_params has an invalid type A present but non-collection claude_platform_unsupported_params was silently ignored, so an operator who mistyped the value (e.g. a string) got the default filtering with no feedback. resolve_unsupported_override now logs a WARNING that names the param in that case, mirroring the existing dropped-param warning. The header-derivation pass passes log_invalid=False so the message is emitted once per request rather than twice on the native /v1/messages path. --- .../bedrock/claude_platform/common_utils.py | 18 ++++++++++--- .../messages_transformation.py | 4 ++- .../bedrock/test_claude_platform_provider.py | 27 +++++++++++-------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/litellm/llms/bedrock/claude_platform/common_utils.py b/litellm/llms/bedrock/claude_platform/common_utils.py index dc530dbbc6f..61c6f345655 100644 --- a/litellm/llms/bedrock/claude_platform/common_utils.py +++ b/litellm/llms/bedrock/claude_platform/common_utils.py @@ -78,18 +78,30 @@ def filter_claude_platform_request_body( def resolve_unsupported_override( litellm_params: Union[dict[str, object], GenericLiteLLMParams], + log_invalid: bool = True, ) -> Optional[frozenset[str]]: """Read ``claude_platform_unsupported_params`` from litellm_params. - Returns None (use default set) when the key is absent. Returns a - frozenset when present, allowing operators to override or clear the - unsupported-param list via proxy config without a code change. + Returns None (use the default set) when the key is absent or set to a + non-collection type; returns a frozenset when a list/set/tuple is given, + letting operators override or clear the unsupported-param list via proxy + config without a code change. A present but non-collection value is a + misconfiguration: it is ignored (defaults apply) and logged at WARNING when + ``log_invalid`` is set, so operators see the override had no effect. The + header-derivation pass disables it so the warning fires once per request. """ raw = litellm_params.get("claude_platform_unsupported_params") if raw is None: return None if isinstance(raw, (list, set, frozenset, tuple)): return frozenset(str(item) for item in raw) + if log_invalid: + verbose_logger.warning( + "bedrock/claude_platform: ignoring claude_platform_unsupported_params " + "of unsupported type %s; expected a list/set/tuple of param names. " + "Using the default unsupported-param set.", + type(raw).__name__, + ) return None diff --git a/litellm/llms/bedrock/claude_platform/messages_transformation.py b/litellm/llms/bedrock/claude_platform/messages_transformation.py index 9948a03fe57..b44371b01f6 100644 --- a/litellm/llms/bedrock/claude_platform/messages_transformation.py +++ b/litellm/llms/bedrock/claude_platform/messages_transformation.py @@ -52,7 +52,9 @@ class BedrockClaudePlatformMessagesConfig( if resolved_api_key and "x-api-key" not in headers: headers["x-api-key"] = resolved_api_key - unsupported_override = resolve_unsupported_override(litellm_params) + unsupported_override = resolve_unsupported_override( + litellm_params, log_invalid=False + ) filtered_optional_params = filter_claude_platform_request_body( optional_params, unsupported_override=unsupported_override, diff --git a/tests/test_litellm/llms/bedrock/test_claude_platform_provider.py b/tests/test_litellm/llms/bedrock/test_claude_platform_provider.py index a535bbfca80..4c3d29a26ed 100644 --- a/tests/test_litellm/llms/bedrock/test_claude_platform_provider.py +++ b/tests/test_litellm/llms/bedrock/test_claude_platform_provider.py @@ -485,26 +485,31 @@ def test_claude_platform_unsupported_override_allows_context_management(): def test_claude_platform_unsupported_override_ignores_invalid_type(): """ If claude_platform_unsupported_params is set to a non-collection type - (e.g. a string), the override is ignored and defaults apply. + (e.g. a string), the override is ignored, defaults apply, and a warning + naming the param is logged so the operator sees it had no effect. """ + from litellm.llms.bedrock.claude_platform import common_utils from litellm.llms.bedrock.claude_platform.transformation import ( BedrockClaudePlatformConfig, ) config = BedrockClaudePlatformConfig() - request_body = config.transform_request( - model="claude-sonnet-4-6", - messages=[{"role": "user", "content": "hello"}], - optional_params={ - "context_management": {"edits": [{"type": "clear_tool_uses_20250919"}]}, - "max_tokens": 10, - }, - litellm_params={"claude_platform_unsupported_params": "not_a_list"}, - headers={}, - ) + with patch.object(common_utils.verbose_logger, "warning") as mock_warning: + request_body = config.transform_request( + model="claude-sonnet-4-6", + messages=[{"role": "user", "content": "hello"}], + optional_params={ + "context_management": {"edits": [{"type": "clear_tool_uses_20250919"}]}, + "max_tokens": 10, + }, + litellm_params={"claude_platform_unsupported_params": "not_a_list"}, + headers={}, + ) assert "context_management" not in request_body assert request_body["max_tokens"] == 10 + warned = [call.args[0] for call in mock_warning.call_args_list] + assert any("claude_platform_unsupported_params" in message for message in warned) def test_claude_platform_messages_does_not_advertise_beta_for_stripped_context_management():