HKUDS/DeepTutor · error · VoiceProviderError
TTS request error: {exc}
Error message
TTS request error: {exc} What it means
While synthesizing speech, the httpx AsyncClient POST to the provider's /audio/speech endpoint raised an httpx.HTTPError (connection failure, timeout, DNS, TLS). The adapter wraps it in VoiceProviderError with the underlying exception text so transport-level failures are visible.
Source
Thrown at deeptutor/services/voice/adapters/openai_compat.py:147
}
if config.voice:
payload["voice"] = config.voice
if config.speed is not None:
payload["speed"] = config.speed
logger.debug(
"TTS synthesize url=%s model=%s voice=%s fmt=%s chars=%d",
url,
config.model,
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
View on GitHub (pinned to 3e82f13042)
Solutions
- Check the embedded httpx error: connect errors mean wrong host/DNS, read timeouts mean increase request_timeout
- Verify network/proxy egress to the provider base_url with curl
- Increase TTSConfig.request_timeout or shorten/split the input text for long syntheses
- If TLS-related, fix the certificate trust of the client environment
Example fix
// before cfg = TTSConfig(base_url=url, api_key=key, request_timeout=5) // after cfg = TTSConfig(base_url=url, api_key=key, request_timeout=60)
Defensive patterns
Strategy: retry
Validate before calling
import httpx
assert (config.base_url or "").startswith(("http://", "https://")), "base_url must be an absolute URL" Try / catch
for attempt in range(3):
try:
return await adapter.synthesize(text, config)
except VoiceProviderError as exc:
if "TTS request error" not in str(exc) or attempt == 2:
raise
await asyncio.sleep(2 ** attempt) Prevention
- Set request_timeout appropriate to model latency (30s+)
- Verify DNS/proxy egress to the provider host before enabling voice
- Retry with exponential backoff only for transport errors, never for config errors
When it happens
Trigger: Provider host unreachable, DNS failure, TLS certificate error, or request_timeout exceeded during the TTS POST. Any non-HTTP-status httpx error triggers this.
Common situations: Wrong/typo'd base_url domain, firewall or proxy blocking egress, self-signed cert on a self-hosted gateway, or a very low request_timeout against a slow TTS model.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- TTS request error: {detail}
- STT request error: {exc}
- Image generation request error: {exc}
- Image generation request error: {exc}
- {self.name}: publish request failed: {exc}
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/77f70058538c6747.
Report an issue: GitHub.