unslothai/unsloth · warning · SttModelIdError

STT model '{model}' is not a curated GGUF dictation model. C

Error message

STT model '{model}' is not a curated GGUF dictation model. Choose one of: {', '.join(GGML_STT_MODELS)}.

What it means

resolve_ggml_model_id only accepts curated GGUF dictation model ids (the GGML_STT_MODELS allowlist); anything non-empty that is not in that list raises SttModelIdError with the valid choices listed in the message. Custom Hugging Face repos are deliberately unsupported for the GGML dictation engine. An empty/None model falls back to the default instead of raising.

Source

Thrown at studio/backend/core/inference/stt_ggml_sidecar.py:111

}
DEFAULT_GGML_STT_MODEL = "small"

_SERVER_START_TIMEOUT_SECONDS = 120.0
_TRANSCRIBE_TIMEOUT_SECONDS = 600.0


class SttEngineUnavailableError(SttUnavailableError):
    """whisper-server is not installed; the GGUF dictation engine is off."""


def resolve_ggml_model_id(model: Optional[str]) -> str:
    """Validate a curated GGML model id. Custom repos are not supported here."""
    if model is None or not str(model).strip():
        return DEFAULT_GGML_STT_MODEL
    normalized = str(model).strip()
    if normalized in GGML_STT_MODELS:
        return normalized
    raise SttModelIdError(
        f"STT model '{model}' is not a curated GGUF dictation model. "
        f"Choose one of: {', '.join(GGML_STT_MODELS)}."
    )


def _managed_whisper_cpp_dir() -> Path:
    """`<STUDIO_HOME>/whisper.cpp` in custom mode, else `~/.unsloth/whisper.cpp`.

    Mirrors `managed_node_dir` / `_find_llama_server_binary` so managed runtimes
    share one parent directory.
    """
    legacy = Path.home() / ".unsloth" / "whisper.cpp"
    try:
        from utils.paths.storage_roots import studio_root

        resolved = studio_root()
        legacy_studio = Path.home() / ".unsloth" / "studio"
        try:

View on GitHub (pinned to 203007d190)

Solutions

  1. Use one of the ids listed in the error message (GGML_STT_MODELS).
  2. Pass None or '' to accept the curated default model.
  3. Need a custom model? Use a different engine path — this one intentionally does not support custom repos.

Example fix

# before
server.ensure_model("openai/whisper-large-v3")
# after
from studio.backend.core.inference.stt_ggml_sidecar import GGML_STT_MODELS
model = next(iter(GGML_STT_MODELS))
server.ensure_model(model)
Defensive patterns

Strategy: validation

Validate before calling

from studio.backend.core.inference.stt_ggml_sidecar import GGML_STT_MODELS
if model_id is not None and model_id.strip() and model_id.strip() not in GGML_STT_MODELS:
    raise ValueError(f"pick one of: {sorted(GGML_STT_MODELS)}")

Type guard

def is_curated_ggml_model(model_id: str | None) -> bool:
    return model_id is None or not model_id.strip() or model_id.strip() in GGML_STT_MODELS

Try / catch

try:
    resolve_ggml_model_id(model_id)
except SttModelIdError as e:
    show_model_picker(list(GGML_STT_MODELS))
    raise

Prevention

When it happens

Trigger: Passing a model id like 'openai/whisper-large-v3' or a custom repo id to ensure_model()/resolve_ggml_model_id instead of one of the curated GGUF ids.

Common situations: Porting code from a diffusers/whisper pipeline that used HF repo ids; typos in curated ids; assuming arbitrary GGUF repos are allowed.

Related errors


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