Repository navigation
TTS: Normalize language for Google #1314
Description
Describe the bug
TTS requests with config.blob.completion.provider = "google-native" skip language
normalization, so a language name like "hindi" reaches Gemini unchanged and the call fails:
[GEMINI] Bad request (code: 400): Invalid language 'hindi' in speech_config.
Provide a valid BCP-47 language code (e.g., 'en-US').
The two providers diverge here:
provider: "google"validates params throughTTSLLMParams
(backend/app/models/llm/request.py:155). Itsnormalize_language_casingvalidator calls
normalize_bcp47_language()(backend/app/models/llm/constants.py:160), mapping
"hindi" -> "hi-IN"beforemap_kaapi_to_google_paramsforwards it.provider: "google-native"is parsed asNativeCompletionConfig
(backend/app/models/llm/request.py:333), whoseparamsis a pass-through
dict[str, Any]. No validator runs, soGoogleAIProvidersets
speech_config["language"] = languageverbatim
(backend/app/services/llm/providers/google_aistudio.py:364-365).
Impact: 635 jobs failed this way in the period reviewed (451 + 184 across two Gemini error
formats) — the largest single source of failures. Each fails in about a second, so these are not
timeouts. STT is unaffected; it defaults to "auto".
The callers are Glific flows whose text_to_speech node sets provider to google-native:
Glific's tts_payload/4 defaults language to "hindi" when the node leaves the field empty.
NGOs are currently told to switch the node to provider: "google" (see glific/glific#6057,
closed with that workaround). This ticket fixes google-native itself rather than waiting for it
to be deprecated.
Expected behavior
google-native TTS accepts the same language inputs as google — language name, bare ISO 639
code, or BCP-47 tag in any casing — and normalizes to the canonical tag before calling Gemini.
Canonical values (hi-IN) pass through unchanged; unrecognized values also pass through, so the
provider still rejects them.
Steps to reproduce
- POST an LLM call with
config.blob.completion={ provider: "google-native", type: "tts", params: { model: "gemini-2.5-flash-preview-tts", voice: "Leda", language: "hindi", response_format: "mp3" } }. - The job fails with the Gemini 400 above, in about a second.
- Repeat with
provider: "google"and identical params — it succeeds, because"hindi"is
normalized to"hi-IN".
Proposed fix
Call normalize_bcp47_language() on the native Google STT/TTS path, where language /
input_language / output_language are read from generation_params
(google_aistudio.py:206-207, :347), so the native and mapped flows share one normalization
point. The function returns unrecognized input unchanged, so this does not widen what the
provider accepts.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTo Do
Activity
[-]LLM Call: Normalize TTS language to BCP-47 on google-native path[/-][+]TTS: Normalize language for Google[/+]