unslothai/unsloth · error · SttModelBusyError

The previous dictation worker did not exit and still holds i

Error message

The previous dictation worker did not exit and still holds its memory. Try again shortly.

What it means

Raised in load() when _release_engine_locked() fails to retire the previous dictation worker child process before starting a new one. The comment explains why: starting a second child over one that never exited would double GPU/CPU memory, so the load refuses and a timer retries the release.

Source

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

            candidate = None
            device: Optional[str] = None
            resident_released = False
            self._start_survivor = None
            try:
                self._raise_if_load_cancelled(cancel_event)
                cached = self._ensure_model_downloaded(model_id)
                snapshot_path = cached.path
                if snapshot_path is None:
                    raise SttModelNotDownloadedError(
                        f"STT model '{model_id}' is not downloaded. "
                        "Download it in Settings, then Voice, before loading it."
                    )
                self._raise_if_load_cancelled(cancel_event)
                device, dtype = _pick_device()
                if not self._release_engine_locked():
                    # Starting a second child over one that never exited doubles
                    # the memory this release was meant to give back.
                    raise SttModelBusyError(
                        "The previous dictation worker did not exit and still holds its "
                        "memory. Try again shortly."
                    )
                resident_released = True
                logger.info("Loading STT model %s (%s) on %s", model_id, snapshot_path, device)

                def not_downloaded(cause: BaseException) -> SttModelNotDownloadedError:
                    return SttModelNotDownloadedError(
                        f"STT model '{model_id}' is not downloaded. "
                        "Download it in Settings, then Voice, before loading it."
                    )

                retry_on_cpu = False
                try:
                    candidate = self._build_model(str(snapshot_path), device, dtype, cancel_event)
                    self._raise_if_load_cancelled(cancel_event)
                except SttLoadCancelledError:
                    raise

View on GitHub (pinned to 203007d190)

Solutions

  1. Simply retry after a short wait — the release timer keeps trying and the next load usually succeeds.
  2. If persistent, inspect for orphaned worker processes (ps | grep the sidecar worker) and kill them manually.
  3. In containers, ensure the init/reaper (e.g. tini) is set so killed children are reaped; check GPU memory with nvidia-smi for a leaked worker.

Example fix

# before
engine = sidecar.load(new_model)  # previous worker alive -> SttModelBusyError
# after
for _ in range(5):
    try:
        engine = sidecar.load(new_model); break
    except SttModelBusyError:
        time.sleep(2)
Defensive patterns

Strategy: retry

Validate before calling

import subprocess
def leaked_workers() -> list[str]:
    out = subprocess.run(["ps", "-eo", "pid,cmd"], capture_output=True, text=True).stdout
    return [l for l in out.splitlines() if "stt" in l and "worker" in l]

Try / catch

for _ in range(5):
    try:
        engine = sidecar.load(model); break
    except SttModelBusyError:
        time.sleep(2)  # release timer retries meanwhile
else:
    kill_leaked_workers(); engine = sidecar.load(model)

Prevention

When it happens

Trigger: Switching models (or reloading after eviction) while the previous worker subprocess has not terminated — it survived its kill signal, is hung in a CUDA call, or is a zombie the reaper has not reaped.

Common situations: Worker stuck in a long GPU kernel or driver teardown; SIGKILL not yet delivered/processed under load; PID namespace or zombie-reaping issues in containers; rapid model switching thrash.

Related errors


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