BerriAI/litellm · error · ValueError
headers is required
Error message
headers is required
What it means
Thrown by SpeechToCompletionBridgeHandler.validate_input_kwargs when 'headers' is absent from kwargs or is not a dict (handler.py:57 — first of the duplicated checks). headers carries the inbound request headers forwarded to the provider; the bridge requires a dict (empty is acceptable). Note lines 55-61 contain a duplicated identical check; only the first can ever raise.
Source
Thrown at litellm/endpoints/speech/speech_to_completion_bridge/handler.py:57
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(
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,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Call through litellm.audio_speech() so headers are normalized to a dict
- If invoking the handler directly, pass headers={} or dict(request.headers)
Example fix
# before
handler.speech(model=m, input=i, voice=v, optional_params={}, litellm_params={}, headers=None, 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
headers = dict(headers) if headers is not None else {}
# httpx.Headers and other mapping types become plain dicts Type guard
def is_headers_dict(headers: object) -> bool:
return isinstance(headers, dict) Try / catch
try:
handler.speech(..., headers=headers, ...)
except ValueError as e:
if "headers is required" in str(e):
headers = dict(inbound_headers or {})
# retry with normalized headers Prevention
- Normalize httpx.Headers / EnvironHeaders to dict before passing
- Default headers to {} when none exist
- Route through litellm.audio_speech() to avoid manual kwargs assembly
When it happens
Trigger: Direct invocation of speech_to_completion_bridge_handler.speech() without headers; headers passed as None or as an httpx.Headers object instead of a plain dict.
Common situations: Custom integrations calling the handler directly and omitting headers; passing httpx.Headers or a werkzeug EnvironHeaders object where a dict is expected.
Related errors
- headers 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/c5e894a175b1774a.
Report an issue: GitHub.