diff --git a/litellm/proxy/common_request_processing.py b/litellm/proxy/common_request_processing.py index a29079433e9..2cfcce2c11c 100644 --- a/litellm/proxy/common_request_processing.py +++ b/litellm/proxy/common_request_processing.py @@ -3431,7 +3431,7 @@ class ProxyBaseLLMRequestProcessing: logging_obj: Final[LiteLLMLoggingObj | None] = self.data.get("litellm_logging_obj", None) _log_llm_api_exception( e, - logging_obj.litellm_call_id if logging_obj is not None else self.data.get("litellm_call_id"), + (logging_obj.litellm_call_id if logging_obj is not None else None) or self.data.get("litellm_call_id"), ) # Allow callbacks to transform the error response transformed_exception: Final = await proxy_logging_obj.post_call_failure_hook( diff --git a/tests/test_litellm/proxy/test_common_request_processing.py b/tests/test_litellm/proxy/test_common_request_processing.py index 98e9d30493a..cdf2118a1c5 100644 --- a/tests/test_litellm/proxy/test_common_request_processing.py +++ b/tests/test_litellm/proxy/test_common_request_processing.py @@ -8671,7 +8671,7 @@ class TestErrorLogCarriesCallId: x-litellm-call-id response header, so a logged exception can be tied to a specific request.""" - async def _invoke(self, data: dict) -> None: + async def _invoke(self, data: dict[str, object]) -> None: from litellm._logging import verbose_proxy_logger processor: Final = ProxyBaseLLMRequestProcessing(data=data) @@ -8712,6 +8712,17 @@ class TestErrorLogCarriesCallId: assert record.litellm_call_id == call_id assert call_id in record.getMessage() + async def test_call_id_falls_back_when_logging_obj_has_none(self, caplog: pytest.LogCaptureFixture) -> None: + call_id: Final = str(uuid.uuid4()) + logging_obj: Final = MagicMock() + logging_obj.litellm_call_id = None + with caplog.at_level("ERROR", logger="LiteLLM Proxy"): + await self._invoke({"litellm_logging_obj": logging_obj, "litellm_call_id": call_id}) + + record: Final = self._error_record(caplog) + assert record.litellm_call_id == call_id + assert call_id in record.getMessage() + def test_client_disconnect_log_carries_call_id(self, caplog: pytest.LogCaptureFixture) -> None: from litellm._logging import verbose_proxy_logger from litellm.proxy.common_request_processing import (