HKUDS/DeepTutor · error · VoiceProviderError
TTS provider returned empty audio.
Error message
TTS provider returned empty audio.
What it means
After a successful HTTP response from /audio/speech, the adapter checks resp.content; an empty body means the provider claimed success but returned zero audio bytes, so a VoiceProviderError is raised rather than returning invalid audio.
Source
Thrown at deeptutor/services/voice/adapters/openai_compat.py:157
config.voice,
response_format,
len(text),
)
try:
async with httpx.AsyncClient(timeout=config.request_timeout) as client:
resp = await client.post(url, headers=headers, json=payload)
except httpx.HTTPError as exc:
raise VoiceProviderError(f"TTS request error: {exc}") from exc
try:
_raise_for_provider(resp, "TTS synthesis")
except VoiceProviderHTTPError as exc:
hint = _openrouter_tts_hint(config)
if hint:
raise VoiceProviderError(f"{exc}{hint}") from exc
raise
audio = resp.content
if not audio:
raise VoiceProviderError("TTS provider returned empty audio.")
content_type = resp.headers.get("content-type") or _FORMAT_CONTENT_TYPES.get(
response_format, "application/octet-stream"
)
# Some gateways return JSON content-type with audio; trust the format map.
if "json" in content_type:
content_type = _FORMAT_CONTENT_TYPES.get(response_format, "audio/mpeg")
return audio, content_type
class OpenRouterTTSAdapter(BaseTTSAdapter):
"""OpenRouter TTS with fallback for streaming chat-audio models.
OpenRouter documents both a dedicated ``/audio/speech`` endpoint for TTS
models and audio output through ``/chat/completions`` for models that expose
the ``audio`` output modality. Try the dedicated endpoint first, then fall
back to chat audio for configs pointed at audio-output chat models.
"""
View on GitHub (pinned to 3e82f13042)
Solutions
- Retry once — some providers intermittently return empty bodies
- Try a different response_format (e.g. mp3 vs wav) or a different voice/model
- If self-hosted, check server logs; if proxied, bypass the proxy to compare
- Report to the provider if it consistently returns 200 with empty content
Defensive patterns
Strategy: retry
Try / catch
try:
audio, ct = await adapter.synthesize(text, config)
except VoiceProviderError as exc:
if "empty audio" in str(exc) and attempt < MAX:
continue # retry — intermittently empty bodies
raise Prevention
- Retry empty-audio responses once or twice
- Validate the chosen response_format against the provider's docs
- Report providers that consistently return 200 with empty bodies
When it happens
Trigger: Provider returns 200 with an empty body — seen with some gateways/proxies that strip binary responses, misconfigured self-hosted TTS, or models that silently produce nothing.
Common situations: A reverse proxy buffering/corrupting binary output, a provider bug for a specific voice/format combination, or an unsupported response_format that the gateway ignores.
Related errors
- {action} failed with HTTP {status_code}: {detail}
- OpenRouter chat audio returned no audio chunks; original /au
- OpenRouter chat audio returned empty audio.
- The model returned an empty response.
- No endpoint URL configured for this provider.
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/d3c84ed29dfc72b5.
Report an issue: GitHub.