unslothai/unsloth · error · SttLanguageError

Language '{language}' is not supported by English-only STT m

Error message

Language '{language}' is not supported by English-only STT model '{model_id}'.

What it means

Raised when a language other than English (or None) is requested for an English-only Whisper model (the '.en' variants). The check happens after _ensure_model_downloaded, whose cached metadata reports is_multilingual=False. Whisper .en models were trained only on English, so a non-English language request can never be honored.

Source

Thrown at studio/backend/core/inference/stt_sidecar.py:1678

        """
        # Reject a missing runtime up front, before the cache and bounded decode.
        ensure_stt_available()
        if cancel_event is not None and cancel_event.is_set():
            raise SttTranscriptionCancelledError("Transcription cancelled.")
        # A set language beats auto-detect. API takes BCP-47; Whisper wants short
        # codes like en or fr.
        lang = normalize_whisper_language(language)
        # Pin the requested id: another request may switch the resident model
        # mid-transcription, so sidecar state is not this request's identity.
        model_id = resolve_model_id(model)
        known_languages = _known_whisper_languages()
        if lang is not None and known_languages is not None and lang not in known_languages:
            raise SttLanguageError(
                f"Language '{language}' is not supported by STT model '{model_id}'."
            )
        cached = self._ensure_model_downloaded(model_id)
        if cached.is_multilingual is False and lang not in (None, "en"):
            raise SttLanguageError(
                f"Language '{language}' is not supported by English-only STT model '{model_id}'."
            )
        decoded_audio = _decode_audio_bounded(audio, cancel_event)
        if cancel_event is not None and cancel_event.is_set():
            raise SttTranscriptionCancelledError("Transcription cancelled.")
        # condition_on_prev_tokens=False stops a fresh clip inheriting prior
        # context, which causes runaway repeats.
        generate_kwargs = {
            "task": "transcribe",
            "condition_on_prev_tokens": False,
            "num_beams": 5,
        }
        if lang is not None:
            generate_kwargs["language"] = lang
        if fast:
            # Short voiced clips: greedy decoding drops beam search for latency.
            generate_kwargs["num_beams"] = 1
        # Serialize inference with model switches and unloads.

View on GitHub (pinned to 203007d190)

Solutions

  1. Switch to the multilingual variant of the model (drop the '.en' suffix, e.g. whisper-base instead of whisper-base.en).
  2. Drop the language argument (None) or set it to 'en' when the English-only model must stay.
  3. Check the model's is_multilingual flag from the download cache before offering non-English languages in the UI.

Example fix

# before
transcribe(audio, model='whisper-base.en', language='fr')

# after
transcribe(audio, model='whisper-base', language='fr')  # multilingual model
Defensive patterns

Strategy: validation

Validate before calling

cached = stt._ensure_model_downloaded(model_id)  # or query your model registry
def allows_language(cached, language):
    from core.inference.stt_sidecar import normalize_whisper_language
    lang = normalize_whisper_language(language)
    return cached.is_multilingual is not False or lang in (None, 'en')

Type guard

def model_accepts_language(is_multilingual: bool | None, language: str | None) -> bool:
    lang = normalize_whisper_language(language)
    return is_multilingual is not False or lang in (None, 'en')

Try / catch

from core.inference.stt_sidecar import SttLanguageError
try:
    text = stt.transcribe(audio, model=model_id, language=lang)
except SttLanguageError:
    text = stt.transcribe(audio, model=multilingual_model_id, language=lang)

Prevention

When it happens

Trigger: Resolving model_id to an English-only checkpoint (e.g. 'whisper-base.en') and calling transcribe with language set to anything other than None or 'en'. The metadata lookup cached.is_multilingual is False triggers the refusal.

Common situations: Default model id points at a '.en' checkpoint while the app lets users pick any language; migrating from a multilingual model to a smaller '.en' one and forgetting to constrain the language picker; auto-detect requests passing a hardcoded language like 'fr'.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/83cead812f65795c. Report an issue: GitHub.