diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index 99a1ba60f25..f90515ac81f 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -2749,9 +2749,10 @@ class Logging(LiteLLMLoggingBaseClass): litellm_params: Final[object] = self.model_call_details.get("litellm_params") if entry is None or not is_str_keyed_dict(litellm_params): return - metadata: Final[object] = litellm_params.setdefault("metadata", {}) - if is_str_keyed_dict(metadata): - with_guardrail_entry(metadata, entry) + metadata: Final[object] = litellm_params.get("metadata") + bucket: Final = metadata if is_str_keyed_dict(metadata) else {} + litellm_params["metadata"] = bucket + with_guardrail_entry(bucket, entry) def _merge_hidden_params_from_response_into_metadata(self, logging_result: object) -> None: """ diff --git a/tests/unit/litellm_core_utils/test_litellm_logging.py b/tests/unit/litellm_core_utils/test_litellm_logging.py index 561ac9b2b33..f44bb1a9050 100644 --- a/tests/unit/litellm_core_utils/test_litellm_logging.py +++ b/tests/unit/litellm_core_utils/test_litellm_logging.py @@ -13642,3 +13642,27 @@ def test_native_messages_body_carries_the_reported_list_cost_into_the_priced_res assert isinstance(priced, ModelResponse) headers = priced._hidden_params.get("additional_headers") or {} assert headers.get("llm_provider-x-litellm-response-cost") == expected_header + + +def test_record_native_bedrock_guardrail_bills_when_the_metadata_is_none() -> None: + import datetime + + from litellm.litellm_core_utils.litellm_logging import Logging + + logging_obj = Logging( + model="bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0", + messages=[{"role": "user", "content": "hello"}], + stream=False, + call_type="completion", + start_time=datetime.datetime.now(), + litellm_call_id="call-none-metadata", + function_id="fn", + ) + logging_obj.model_call_details["litellm_params"] = {"metadata": None} + trace = {"guardrail": {"inputAssessment": {"gid": {"invocationMetrics": {"usage": {"contentPolicyUnits": 2}}}}}} + + logging_obj.record_native_bedrock_guardrail({"trace": trace}) + + (entry,) = logging_obj.model_call_details["litellm_params"]["metadata"]["standard_logging_guardrail_information"] + assert entry["guardrail_usage"] == {"contentPolicyUnits": 2} + assert entry["guardrail_cost"] > 0