BerriAI/litellm · error · ValueError
optional_params is required
Error message
optional_params is required
What it means
Thrown by SpeechToCompletionBridgeHandler.validate_input_kwargs when 'optional_params' is absent from kwargs or is not a dict (handler.py:49). optional_params carries extra call options (e.g. audio voice/format, response_format) that the bridge forwards to the underlying completion() call; it must be a dict even when empty.
Source
Thrown at litellm/endpoints/speech/speech_to_completion_bridge/handler.py:49
def validate_input_kwargs(self, kwargs: dict) -> SpeechToCompletionBridgeHandlerInputKwargs:
from litellm import LiteLLMLoggingObj
model: Final = kwargs.get("model")
if model is None or not isinstance(model, str):
raise ValueError("model is required")
custom_llm_provider: Final = kwargs.get("custom_llm_provider")
if custom_llm_provider is None or not isinstance(custom_llm_provider, str):
raise ValueError("custom_llm_provider is required")
input: Final = kwargs.get("input")
if input is None or not isinstance(input, str):
raise ValueError("input is required")
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(View on GitHub (pinned to 6c2dcb801b)
Solutions
- Call litellm.audio_speech() instead of the handler directly so optional_params is populated as {} by default
- If invoking directly, always pass optional_params={} when there are no extra options
- Verify no middleware mutates optional_params to a non-dict value
Example fix
# before
handler.speech(model=m, input=i, voice=v, optional_params=None, litellm_params={}, headers={}, logging_obj=log, custom_llm_provider="openai")
# after
handler.speech(model=m, input=i, voice=v, optional_params={}, litellm_params={}, headers={}, logging_obj=log, custom_llm_provider="openai") Defensive patterns
Strategy: validation
Validate before calling
optional_params = optional_params if isinstance(optional_params, dict) else {}
# then pass through, or simply rely on litellm.audio_speech() defaults Type guard
def is_optional_params_valid(params: object) -> bool:
return isinstance(params, dict) Try / catch
try:
handler.speech(..., optional_params=optional_params, ...)
except ValueError as e:
if "optional_params is required" in str(e):
optional_params = {}
# retry once with corrected args Prevention
- Default optional_params to {} wherever you build TTS kwargs
- Call litellm.audio_speech() instead of the internal handler
- Add a shape check on dynamically assembled kwargs before invocation
When it happens
Trigger: Calling speech_to_completion_bridge_handler.speech() directly with optional_params=None or omitted; passing optional_params as a list or object instead of dict.
Common situations: Custom direct invocations of the handler; refactors where optional_params is conditionally built and ends up None; mocked tests that skip the argument.
Related errors
- optional_params 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/d6740269236c999e.
Report an issue: GitHub.