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

  1. Set base_url on the TTSConfig / voice provider settings (e.g. https://api.openai.com/v1)
  2. Check data/user/settings/*.json and process-env overrides for an empty voice endpoint
  3. 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

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


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/d63177eb3bccce91. Report an issue: GitHub.