unslothai/unsloth · error · SttModelNotDownloadedError

STT model '{model_id}' is not downloaded. Download it in Set

Error message

STT model '{model_id}' is not downloaded. Download it in Settings, then Voice, before loading it.

What it means

Raised by _ensure_model_downloaded() as SttModelNotDownloadedError when _cached_model_paths(model_id) returns None, meaning the mtmd (multimodal Whisper) model files are not present in the local cache. Both load() and transcribe() call it up front so a missing model fails fast before any server start or audio decode.

Source

Thrown at studio/backend/core/inference/stt_mtmd_sidecar.py:792

        self._update_in_progress = True
        try:
            with self._start_lock, self._lock:
                model_was_active = self._process_alive()
                self._release_locked()
                yield model_was_active
        finally:
            self._update_in_progress = False

    @staticmethod
    def _reserve_free_port() -> tuple[socket.socket, int]:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(("127.0.0.1", 0))
        return sock, sock.getsockname()[1]

    def _ensure_model_downloaded(self, model_id: str) -> tuple[str, str]:
        paths = _cached_model_paths(model_id)
        if paths is None:
            raise SttModelNotDownloadedError(
                f"STT model '{model_id}' is not downloaded. "
                "Download it in Settings, then Voice, before loading it."
            )
        return paths

    def load(
        self,
        model: Optional[str] = None,
        request_cancel_event: Optional[threading.Event] = None,
    ) -> None:
        if request_cancel_event is not None and request_cancel_event.is_set():
            raise SttTranscriptionCancelledError("Transcription cancelled.")
        self._raise_if_update_in_progress()
        model_id = resolve_mtmd_model_id(model)
        binary = ensure_engine_available()
        # Startup happens outside _lock (it is slow), so this keeps two callers
        # from each spawning a server and orphaning the first.
        with self._start_lock:

View on GitHub (pinned to 203007d190)

Solutions

  1. Download the model in Settings > Voice before loading it.
  2. Verify the model cache directory exists and contains the model and mmproj files for that model_id.
  3. Call the download API/route for the model first, then retry the load.
Defensive patterns

Strategy: validation

Validate before calling

```python
from studio.backend.core.inference.stt_mtmd_sidecar import _cached_model_paths

if _cached_model_paths(model_id) is None:
    prompt_download(model_id)  # Settings > Voice flow
```

Try / catch

```python
try:
    sidecar.load(model_id)
except SttModelNotDownloadedError:
    start_download_flow(model_id)  # then retry after completion
```

Prevention

When it happens

Trigger: load(model) or transcribe_bytes(...) with a model id whose GGUF model/mmproj files were never downloaded via the Settings > Voice download flow, or whose cache directory was deleted/moved.

Common situations: Fresh install with no model downloaded; user pointed the cache at a wiped directory; model files removed after a disk cleanup; requesting a second model that was never fetched.

Related errors


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