BerriAI/litellm · error · ValueError
logging_obj is required
Error message
logging_obj is required
What it means
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.
Source
Thrown at litellm/endpoints/speech/speech_to_completion_bridge/handler.py:65
optional_params: Final = kwargs.get("optional_params")
if optional_params is None or not isinstance(optional_params, dict):
raise ValueError("optional_params is required")
litellm_params: Final = kwargs.get("litellm_params")
if litellm_params is None or not isinstance(litellm_params, dict):
raise ValueError("litellm_params is required")
headers = kwargs.get("headers")
if headers is None or not isinstance(headers, dict):
raise ValueError("headers is required")
headers = kwargs.get("headers")
if headers is None or not isinstance(headers, dict):
raise ValueError("headers is required")
logging_obj: Final = kwargs.get("logging_obj")
if logging_obj is None or not isinstance(logging_obj, LiteLLMLoggingObj):
raise ValueError("logging_obj is required")
return SpeechToCompletionBridgeHandlerInputKwargs(
model=model,
input=input,
voice=kwargs.get("voice"),
optional_params=optional_params,
litellm_params=litellm_params,
logging_obj=logging_obj,
custom_llm_provider=custom_llm_provider,
headers=headers,
)
def speech(
self,
model: str,
input: str,
voice: str | dict | None,
optional_params: dict,View on GitHub (pinned to 6c2dcb801b)
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
Example fix
# before
handler.speech(model=m, input=i, voice=v, optional_params={}, litellm_params={}, headers={}, logging_obj=None, custom_llm_provider="openai")
# after
from litellm.litellm_core_utils.litellm_logging import LiteLLMLoggingObj
logging_obj = LiteLLMLoggingObj(model=m, messages=[], stream=False, call_type="audio_speech")
handler.speech(model=m, input=i, voice=v, optional_params={}, litellm_params={}, headers={}, logging_obj=logging_obj, custom_llm_provider="openai") Defensive patterns
Strategy: type-guard
Validate before calling
from litellm.litellm_core_utils.litellm_logging import LiteLLMLoggingObj
if not isinstance(logging_obj, LiteLLMLoggingObj):
logging_obj = LiteLLMLoggingObj(model=model, messages=[], stream=False, call_type="audio_speech") Type guard
from litellm.litellm_core_utils.litellm_logging import LiteLLMLoggingObj
def is_valid_logging_obj(obj: object) -> bool:
return isinstance(obj, LiteLLMLoggingObj) Try / catch
try:
handler.speech(..., logging_obj=logging_obj, ...)
except ValueError as e:
if "logging_obj is required" in str(e):
logger.error("logging_obj must be a LiteLLMLoggingObj instance; use litellm.audio_speech()")
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- logging_obj is required
- prompt_characters must be provided for tts calls. prompt_cha
- model is required
- custom_llm_provider is required
- input is required
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/001f58aff74a3d86.
Report an issue: GitHub.