HKUDS/DeepTutor · error · VoiceProviderError
No endpoint URL configured for TTS.
Error message
No endpoint URL configured for TTS.
What it means
OpenAICompatTTSAdapter.synthesize POSTs to {base_url}/audio/speech and requires a non-empty config.base_url. With no base URL the adapter cannot form the endpoint and raises VoiceProviderError before any request. It is the primary guard for TTS endpoint configuration.
Source
Thrown at deeptutor/services/voice/adapters/openai_compat.py:117
if (
config.provider_name == "openrouter"
and "gemini" in model
and "tts" in model
and voice.lower() in _OPENAI_TTS_VOICES
):
return (
f" Voice `{voice}` is an OpenAI TTS voice; Gemini TTS expects Google "
"prebuilt voice names such as `Kore` or `Puck`."
)
return ""
class OpenAICompatTTSAdapter(BaseTTSAdapter):
"""POST ``{base}/audio/speech`` with a JSON body, returning raw audio bytes."""
async def synthesize(self, text: str, config: TTSConfig) -> tuple[bytes, str]:
if not config.base_url:
raise VoiceProviderError("No endpoint URL configured for TTS.")
url = join_audio_path(config.base_url, "audio/speech")
headers = {
"Content-Type": "application/json",
**build_auth_headers(config.auth_style, config.api_key),
**(config.extra_headers or {}),
}
response_format = (config.response_format or "mp3").lower()
payload: dict[str, Any] = {
"model": config.model,
"input": text,
"response_format": response_format,
}
if config.voice:
payload["voice"] = config.voice
if config.speed is not None:
payload["speed"] = config.speed
logger.debug(View on GitHub (pinned to 3e82f13042)
Solutions
- Set base_url on the TTSConfig / voice provider settings (e.g. https://api.openai.com/v1)
- Check data/user/settings/*.json and process-env overrides for an empty voice endpoint
- Add startup validation of voice provider config
Example fix
// before
await adapter.synthesize("hi", TTSConfig(base_url="", api_key=key))
// after
await adapter.synthesize("hi", TTSConfig(base_url="https://api.openai.com/v1", api_key=key)) Defensive patterns
Strategy: validation
Validate before calling
if not (tts_config.base_url or "").strip():
raise ValueError("TTS base_url must be configured") Try / catch
try:
audio, content_type = await adapter.synthesize(text, config)
except VoiceProviderError as exc:
if "No endpoint URL configured for TTS" in str(exc):
# config problem, not transient — do not retry
alert_admin_missing_tts_endpoint() Prevention
- Populate base_url whenever an api_key is set for a voice provider
- Fail fast on startup with a settings validator
When it happens
Trigger: Calling synthesize(text, config) where TTSConfig.base_url is empty/None — e.g. the voice provider entry in settings has an API key but no endpoint.
Common situations: Admin configured only an api_key assuming a default OpenAI endpoint, settings JSON lost the base_url field, or an env var override set it to an empty string.
Related errors
- No endpoint URL configured for this provider.
- No endpoint URL configured for STT.
- No endpoint URL configured for this provider.
- TTS request error: {exc}
- {exc}{hint}
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/d63177eb3bccce91.
Report an issue: GitHub.