diff --git a/litellm/proxy/guardrails/guardrail_hooks/bedrock_guardrails.py b/litellm/proxy/guardrails/guardrail_hooks/bedrock_guardrails.py index fb790a44779..2ce63cee89b 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/bedrock_guardrails.py +++ b/litellm/proxy/guardrails/guardrail_hooks/bedrock_guardrails.py @@ -265,6 +265,14 @@ class BedrockGuardrail(CustomGuardrail, BaseAWSLLM): checks = checks.model_dump(exclude_none=True) if not isinstance(checks, dict): return None + unknown_keys = set(checks.keys()) - _BEDROCK_CHECKS_KNOWN_KEYS + if unknown_keys: + verbose_proxy_logger.warning( + "BedrockGuardrail: unrecognized check key(s) %s will be ignored. " + "Known keys: %s. Guardrail will fall back to ApplyGuardrail mode.", + sorted(unknown_keys), + sorted(_BEDROCK_CHECKS_KNOWN_KEYS), + ) cleaned = { key: value for key, value in checks.items() diff --git a/tests/guardrails_tests/test_bedrock_guardrails.py b/tests/guardrails_tests/test_bedrock_guardrails.py index 9bdb6dd159d..67c27b44b5b 100644 --- a/tests/guardrails_tests/test_bedrock_guardrails.py +++ b/tests/guardrails_tests/test_bedrock_guardrails.py @@ -20,6 +20,24 @@ def test_bedrock_normalize_checks_keeps_empty_known_check_config(): } +def test_bedrock_normalize_checks_warns_on_unknown_keys(caplog): + import logging + + with caplog.at_level(logging.WARNING, logger="LiteLLM Proxy"): + result = BedrockGuardrail._normalize_checks({"contentFilter": {}, "typo_key": True}) + assert result == {"contentFilter": {}} + assert any("typo_key" in m for m in caplog.messages) + + +def test_bedrock_normalize_checks_all_unknown_returns_none_with_warning(caplog): + import logging + + with caplog.at_level(logging.WARNING, logger="LiteLLM Proxy"): + result = BedrockGuardrail._normalize_checks({"snake_case_typo": True}) + assert result is None + assert any("snake_case_typo" in m for m in caplog.messages) + + @pytest.mark.asyncio async def test_bedrock_guardrails_pii_masking(): # Create proper mock objects