unslothai/unsloth · error · SttModelNotDownloadedError

STT model '{model_id}' (GGUF) is not downloaded. Download it

Error message

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

What it means

Raised by GgmlSttSidecar._ensure_model_downloaded when _cached_model_path(model_id) returns None, i.e. the requested curated GGUF model is not present in the local cache. The GGML sidecar never downloads models on demand; the user must fetch them via the Settings > Voice UI first.

Source

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

            pass

    @staticmethod
    def _reserve_free_port() -> tuple[socket.socket, int]:
        """Bind an ephemeral port and keep the socket held.

        The caller closes the reservation immediately before spawning
        whisper-server, shrinking the window in which another local process
        could bind the port. SO_REUSEADDR lets the child rebind right after.
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(("127.0.0.1", 0))
        return s, s.getsockname()[1]

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

    def load(
        self,
        model: Optional[str] = None,
        request_cancel_event: Optional[threading.Event] = None,
    ) -> None:
        """Start (or switch) whisper-server for the requested curated model."""
        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_ggml_model_id(model)
        with self._lock:
            if request_cancel_event is not None and request_cancel_event.is_set():
                raise SttTranscriptionCancelledError("Transcription cancelled.")

View on GitHub (pinned to 203007d190)

Solutions

  1. Download the model in Settings > Voice in the Studio UI, then retry.
  2. Verify the model id is one of the curated GGUF ids so it maps to a cacheable path.
  3. Check the models cache directory is writable and was not wiped by a cleanup tool.
Defensive patterns

Strategy: validation

Validate before calling

from core.inference.stt_ggml_sidecar import _cached_model_path
if _cached_model_path(resolve_ggml_model_id(model)) is None:
    prompt_user_to_download(model)  # Settings > Voice
    return

Type guard

def model_is_cached(model: str) -> bool:
    return _cached_model_path(resolve_ggml_model_id(model)) is not None

Try / catch

try:
    sidecar.load(model_id)
except SttModelNotDownloadedError:
    open_settings_voice_tab(model_id)

Prevention

When it happens

Trigger: Calling load(model) or transcribe() (which preflights via _ensure_model_downloaded before decoding audio) with a curated model id whose GGUF file is missing from the cache directory.

Common situations: Fresh install where no dictation model was downloaded yet; the models cache directory was cleared or moved; the model id resolves to a curated id the user never selected; a failed/interrupted earlier download left no complete file.

Related errors


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