unslothai/unsloth · warning · SttModelIdError

Another GGUF dictation model ('{self._model_id}') is still d

Error message

Another GGUF dictation model ('{self._model_id}') is still downloading; wait for it to finish.

What it means

Raised by the downloader's ensure() when a download thread is alive for a DIFFERENT model id. The downloader is single-model by design: starting a second concurrent download would clobber shared state (_model_id, progress, cancel flag). The lock makes the check atomic, and the error names the model still in flight so the caller can wait or cancel it first.

Source

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

            return None

    def start(
        self,
        model_id: str,
        hf_token: Optional[str] = None,
    ) -> None:
        model_id = resolve_ggml_model_id(model_id)
        hub_cache = _capture_stt_hub_cache()
        with self._lock:
            if self._thread is not None and self._thread.is_alive():
                if self._model_id == model_id:
                    # Joining a cancelling run would silently download nothing.
                    if not self._cancelled:
                        return
                    raise SttModelIdError(
                        f"'{model_id}' is still cancelling; try again in a moment."
                    )
                raise SttModelIdError(
                    f"Another GGUF dictation model ('{self._model_id}') is still "
                    "downloading; wait for it to finish."
                )
            self._model_id = model_id
            self._error = None
            self._total_bytes = None
            self._etag = None
            self._revision = None
            self._hub_cache = hub_cache
            self._cancelled = False
            self._process = None
            thread = threading.Thread(
                target = self._run,
                args = (model_id, hf_token),
                daemon = True,
            )
            self._thread = thread
            thread.start()

View on GitHub (pinned to 203007d190)

Solutions

  1. Wait for the in-flight download to finish (poll progress/alive status) before requesting the new model.
  2. Cancel the current download first, wait for its cancellation to settle, then ensure the new model.
  3. Serialize model-switch requests client-side so ensure() is never called concurrently.

Example fix

# before
downloader.ensure(model_b)  # while model_a still downloading
# after
while downloader.is_downloading():
    time.sleep(0.5)
downloader.ensure(model_b)
Defensive patterns

Strategy: validation

Validate before calling

while downloader.is_downloading():
    time.sleep(0.5)  # or offer to cancel the current model first

Type guard

def downloader_idle(downloader) -> bool:
    t = downloader._thread
    return t is None or not t.is_alive()

Try / catch

try:
    downloader.ensure(model_id)
except SttModelIdError as e:
    if "still downloading" in str(e):
        wait_or_cancel_current_then_retry(model_id)
    raise

Prevention

When it happens

Trigger: Calling ensure('model-b') while ensure('model-a') is still downloading in its background thread — e.g. a user switching dictation models rapidly in the UI.

Common situations: Quick model switching in a settings panel; parallel requests from multiple clients hitting the same downloader instance.

Related errors


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