{"record":{"id":"001f58aff74a3d86","repo":"BerriAI/litellm","slug":"logging-obj-is-required-001f58","errorCode":null,"errorMessage":"logging_obj is required","messagePattern":"logging_obj is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/endpoints/speech/speech_to_completion_bridge/handler.py","lineNumber":65,"sourceCode":"        optional_params: Final = kwargs.get(\"optional_params\")\n        if optional_params is None or not isinstance(optional_params, dict):\n            raise ValueError(\"optional_params is required\")\n\n        litellm_params: Final = kwargs.get(\"litellm_params\")\n        if litellm_params is None or not isinstance(litellm_params, dict):\n            raise ValueError(\"litellm_params is required\")\n\n        headers = kwargs.get(\"headers\")\n        if headers is None or not isinstance(headers, dict):\n            raise ValueError(\"headers is required\")\n\n        headers = kwargs.get(\"headers\")\n        if headers is None or not isinstance(headers, dict):\n            raise ValueError(\"headers is required\")\n\n        logging_obj: Final = kwargs.get(\"logging_obj\")\n        if logging_obj is None or not isinstance(logging_obj, LiteLLMLoggingObj):\n            raise ValueError(\"logging_obj is required\")\n\n        return SpeechToCompletionBridgeHandlerInputKwargs(\n            model=model,\n            input=input,\n            voice=kwargs.get(\"voice\"),\n            optional_params=optional_params,\n            litellm_params=litellm_params,\n            logging_obj=logging_obj,\n            custom_llm_provider=custom_llm_provider,\n            headers=headers,\n        )\n\n    def speech(\n        self,\n        model: str,\n        input: str,\n        voice: str | dict | None,\n        optional_params: dict,","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/endpoints/speech/speech_to_completion_bridge/handler.py#L47-L83","documentation":"Thrown by SpeechToCompletionBridgeHandler.validate_input_kwargs when 'logging_obj' is absent from kwargs or is not an instance of litellm.LiteLLMLoggingObj (handler.py:65). The bridge logs the underlying completion call, so a properly constructed logging object is mandatory — a dict or None substitute is rejected.","triggerScenarios":"Direct invocation of speech_to_completion_bridge_handler.speech() with logging_obj=None or a custom class; passing a mock that does not subclass LiteLLMLoggingObj.","commonSituations":"Bypassing litellm.audio_speech(); unit tests using unittest.Mock instead of a real or subclassed logging object; older litellm versions where the logging class import path moved.","solutions":["Route calls through litellm.audio_speech() so the router creates the logging object","If invoking the handler directly, construct one via litellm.litellm_core_utils.litellm_logging.LiteLLMLoggingObj (or LoggingCallbackManager) and pass it","In tests, subclass LiteLLMLoggingObj or use an actual instance rather than a bare Mock"],"exampleFix":"# before\nhandler.speech(model=m, input=i, voice=v, optional_params={}, litellm_params={}, headers={}, logging_obj=None, custom_llm_provider=\"openai\")\n\n# after\nfrom litellm.litellm_core_utils.litellm_logging import LiteLLMLoggingObj\nlogging_obj = LiteLLMLoggingObj(model=m, messages=[], stream=False, call_type=\"audio_speech\")\nhandler.speech(model=m, input=i, voice=v, optional_params={}, litellm_params={}, headers={}, logging_obj=logging_obj, custom_llm_provider=\"openai\")","handlingStrategy":"type-guard","validationCode":"from litellm.litellm_core_utils.litellm_logging import LiteLLMLoggingObj\nif not isinstance(logging_obj, LiteLLMLoggingObj):\n    logging_obj = LiteLLMLoggingObj(model=model, messages=[], stream=False, call_type=\"audio_speech\")","typeGuard":"from litellm.litellm_core_utils.litellm_logging import LiteLLMLoggingObj\n\ndef is_valid_logging_obj(obj: object) -> bool:\n    return isinstance(obj, LiteLLMLoggingObj)","tryCatchPattern":"try:\n    handler.speech(..., logging_obj=logging_obj, ...)\nexcept ValueError as e:\n    if \"logging_obj is required\" in str(e):\n        logger.error(\"logging_obj must be a LiteLLMLoggingObj instance; use litellm.audio_speech()\")\n        raise","preventionTips":["Let litellm construct logging objects by using public entrypoints","In tests, subclass LiteLLMLoggingObj rather than using bare Mocks","Pin the logging class import path when upgrading litellm versions"],"tags":["validation","tts","logging","type-check"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}