{"record":{"id":"3426a17d779b5396","repo":"unslothai/unsloth","slug":"language-language-is-not-supported-by-stt-mode-3426a1","errorCode":null,"errorMessage":"Language '{language}' is not supported by STT model '{model_id}'.","messagePattern":"Language '(.+?)' is not supported by STT model '(.+?)'\\.","errorType":"http","errorClass":"SttLanguageError","httpStatus":422,"severity":"error","filePath":"studio/backend/core/inference/stt_sidecar.py","lineNumber":1673,"sourceCode":"    ) -> dict:\n        \"\"\"Transcribe encoded audio bytes to text.\n\n        Accepts any container PyAV can decode: wav, mp3, opus/webm, ogg,\n        m4a/aac. Returns {text, language, duration, model}.\n        \"\"\"\n        # Reject a missing runtime up front, before the cache and bounded decode.\n        ensure_stt_available()\n        if cancel_event is not None and cancel_event.is_set():\n            raise SttTranscriptionCancelledError(\"Transcription cancelled.\")\n        # A set language beats auto-detect. API takes BCP-47; Whisper wants short\n        # codes like en or fr.\n        lang = normalize_whisper_language(language)\n        # Pin the requested id: another request may switch the resident model\n        # mid-transcription, so sidecar state is not this request's identity.\n        model_id = resolve_model_id(model)\n        known_languages = _known_whisper_languages()\n        if lang is not None and known_languages is not None and lang not in known_languages:\n            raise SttLanguageError(\n                f\"Language '{language}' is not supported by STT model '{model_id}'.\"\n            )\n        cached = self._ensure_model_downloaded(model_id)\n        if cached.is_multilingual is False and lang not in (None, \"en\"):\n            raise SttLanguageError(\n                f\"Language '{language}' is not supported by English-only STT model '{model_id}'.\"\n            )\n        decoded_audio = _decode_audio_bounded(audio, cancel_event)\n        if cancel_event is not None and cancel_event.is_set():\n            raise SttTranscriptionCancelledError(\"Transcription cancelled.\")\n        # condition_on_prev_tokens=False stops a fresh clip inheriting prior\n        # context, which causes runaway repeats.\n        generate_kwargs = {\n            \"task\": \"transcribe\",\n            \"condition_on_prev_tokens\": False,\n            \"num_beams\": 5,\n        }\n        if lang is not None:","sourceCodeStart":1655,"sourceCodeEnd":1691,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/stt_sidecar.py#L1655-L1691","documentation":"Raised by the STT sidecar's transcribe path when an explicitly requested language, after normalization to a Whisper short code (e.g. 'en-US' -> 'en'), is not in Whisper's known language set. The check runs before model download and audio decode, so it fires fast and cheap. It exists because Whisper can only transcribe its ~99 trained languages; anything else would fail or hallucinate inside generation.","triggerScenarios":"Calling transcribe(..., language='xx') where normalize_whisper_language maps the BCP-47 tag to a code absent from _known_whisper_languages(), while a Whisper family model is the target. Only fires when the known-language set is available (not None) and language is not None.","commonSituations":"Passing a macro-language tag Whisper does not train (e.g. 'cn', 'zz', invented codes); passing a locale Whisper maps to nothing; a UI dropdown seeded with ISO-639-3 codes instead of the BCP-47 subset Whisper supports; a typo like 'eng' instead of 'en'.","solutions":["Pass a language Whisper supports, preferably the short code ('en', 'fr', 'de') or a BCP-47 tag that normalizes to one.","Omit language (pass None) to let Whisper auto-detect the spoken language.","Validate the value against the tokenizer's language set (or core.inference.stt_sidecar._known_whisper_languages()) before calling transcribe."],"exampleFix":"# before\ntranscribe(audio, language='eng')  # not a Whisper code\n\n# after\ntranscribe(audio, language='en')   # Whisper short code\n# or omit for auto-detect:\ntranscribe(audio, language=None)","handlingStrategy":"validation","validationCode":"from core.inference.stt_sidecar import normalize_whisper_language, _known_whisper_languages\n\ndef is_supported_stt_language(language):\n    lang = normalize_whisper_language(language)\n    known = _known_whisper_languages()\n    return lang is None or known is None or lang in known","typeGuard":"def valid_whisper_language(language: str | None) -> bool:\n    lang = normalize_whisper_language(language)\n    known = _known_whisper_languages()\n    return lang is None or known is None or lang in known","tryCatchPattern":"from core.inference.stt_sidecar import SttLanguageError\ntry:\n    text = stt.transcribe(audio, language=lang)\nexcept SttLanguageError as e:\n    # fall back to auto-detect; the language is unusable, not the audio\n    text = stt.transcribe(audio, language=None)","preventionTips":["Constrain language pickers to the BCP-47 subset Whisper actually supports.","Normalize through normalize_whisper_language client-side so validation matches the backend's mapping.","Default to None (auto-detect) when the source of the language string is untrusted."],"tags":["stt","whisper","language","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}