BerriAI/litellm · error · BaseLLMException
{error_message}
Error message
{error_message} What it means
The generic error constructor of BaseTextToSpeechConfig: when a TTS request fails at the HTTP layer (non-2xx), litellm calls get_error_class(), which raises BaseLLMException carrying the provider's message ('{error_message}' in the traceback is that verbatim text), the status code, and headers. Callers usually see it mapped to a litellm.*StatusError or the raw BaseLLMException.
Source
Thrown at litellm/llms/base_llm/text_to_speech/transformation.py:139
- body: The request body (JSON dict, XML string, or binary data)
- headers: Provider-specific headers to merge with base headers
"""
@abstractmethod
def transform_text_to_speech_response(
self,
model: str,
raw_response: httpx.Response,
logging_obj: LiteLLMLoggingObj,
) -> "HttpxBinaryResponseContent":
"""
Transform provider response to standard format
"""
def get_error_class(self, error_message: str, status_code: int, headers: dict) -> BaseLLMException:
from ..chat.transformation import BaseLLMException
raise BaseLLMException(
status_code=status_code,
message=error_message,
headers=headers,
)
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Inspect status_code and the provider message on the exception; the root cause is almost always the upstream request (auth, voice, format, endpoint path).
- Validate voice/format against the provider's supported list before calling.
- For self-hosted backends, confirm the api_base path matches the OpenAI /audio/speech schema.
- Handle 429 with retries/backoff via litellm's num_retries or router fallbacks.
Example fix
# before
resp = litellm.text_to_speech(model="openai/tts-1", voice="sarah", input="hi") # unknown voice
# after
resp = litellm.text_to_speech(model="openai/tts-1", voice="alloy", input="hi") # supported voice
try:
resp = litellm.text_to_speech(model="openai/tts-1", voice="alloy", input="hi")
except Exception as e:
status = getattr(e, "status_code", None)
if status == 400:
logger.warning("bad TTS request: %s", e) Defensive patterns
Strategy: try-catch
Validate before calling
SUPPORTED_VOICES = {"alloy", "echo", "fable", "onyx", "nova", "shimmer"}
assert voice in SUPPORTED_VOICES, f"unsupported voice {voice}" Type guard
def is_tts_provider_error(e: BaseException) -> bool:
return getattr(e, "__class__", None).__name__ == "BaseLLMException" and hasattr(e, "status_code") Try / catch
try:
speech = litellm.text_to_speech(model="openai/tts-1", voice=voice, input=text)
except BaseLLMException as e:
if e.status_code == 400:
voice = "alloy" # fall back to a universally supported voice
speech = litellm.text_to_speech(model="openai/tts-1", voice=voice, input=text)
else:
raise Prevention
- Pin voice/format pairs validated against the provider's docs before calling.
- For self-hosted TTS, verify the endpoint implements the OpenAI /audio/speech schema.
When it happens
Trigger: litellm.text_to_speech() hitting provider errors: 401 bad key, 400 unsupported voice/format combination, 429 quota, 5xx provider outage — the transformation layer converts the failed response into BaseLLMException.
Common situations: Wrong voice name for the model; requesting an unsupported response_format (e.g. mp3 vs wav/opus on some backends); expired keys; self-hosted TTS server returning 404 because the route doesn't match the OpenAI schema.
Related errors
- {error_message}
- {error_message}
- {error_message}
- api_base is required
- Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/9460ba7c8dce79a8.
Report an issue: GitHub.