unslothai/unsloth · error · RuntimeError

A diffusion load is already in progress.

Error message

A diffusion load is already in progress.

What it means

Concurrency guard inside the load lock: a new diffusion load is refused while another load is in progress. The check is `self._loading is not None and self._loading.error is None` - i.e. a LIVE load blocks, but a previously FAILED one does not (starting over a failed load is explicitly allowed). A fresh cancel_event and incremented token are created per load so an unload() can preempt the running worker's download.

Source

Thrown at studio/backend/core/inference/diffusion.py:1813

            family_override = family_override,
            model_kind = model_kind,
        )
        # Refuse an EXPLICIT precision this host can never honor BEFORE the load starts, so the
        # route answers 409 with the reason instead of evicting the resident model, downloading
        # several GB and only then failing. The declines that need the real footprint (a VRAM
        # misfit, a failed build) can only be found mid-load and surface through load-progress.
        self.assert_precision_available(
            fam,
            model_kind = resolve_model_kind(gguf_filename, model_kind),
            transformer_quant = transformer_quant,
            text_encoder_quant = text_encoder_quant,
            gpu_ordinal = gpu_ordinal,
        )

        with self._lock:
            # Allow starting over a previously-failed load, but not over a live one.
            if self._loading is not None and self._loading.error is None:
                raise RuntimeError("A diffusion load is already in progress.")
            self._load_token += 1
            token = self._load_token
            # A NEW event per load, never a clear() of the shared one: unload() sets the event the running worker holds but also
            # drops _loading, so clearing here would un-cancel that worker. Download preemption is best-effort; the token is the
            # real commit guard.
            cancel_event = threading.Event()
            self._cancel_event = cancel_event
            # Seed with the family fallback; the worker resolves the real base and updates this.
            self._loading = _LoadingState(repo_id = repo_id, base_repo = fam.base_repo)

        threading.Thread(
            target = self._run_load,
            kwargs = dict(
                repo_id = repo_id,
                gguf_filename = gguf_filename,
                base_repo = base_repo,
                family_override = family_override,
                hf_token = hf_token,

View on GitHub (pinned to 203007d190)

Solutions

  1. Wait for the in-progress load to finish (poll the load-progress/status surface) before issuing another.
  2. If the running load is wrong or stuck, call unload() first - it cancels the worker via the cancel event - then start the new load.
  3. In automation, serialize loads behind a queue or lock on the caller side so only one load request is ever outstanding.
  4. Note a FAILED load does not block: if this error appears with no visible load, inspect _loading.error - a stale failed state should have been cleared.

Example fix

# before: fire-and-forget second load
manager.load(repo_id="unsloth/FLUX.1-dev")     # still downloading
manager.load(repo_id="unsloth/SD3.5-large")     # RuntimeError: already in progress

# after: wait for idle, or unload first
while manager.is_loading():
    time.sleep(0.5)
manager.load(repo_id="unsloth/SD3.5-large")
Defensive patterns

Strategy: retry

Validate before calling

def can_start_load(manager) -> bool:
    """True when no live load is running (a failed one does not block)."""
    loading = manager._loading  # or the public load-progress/status surface
    return loading is None or loading.error is not None

Try / catch

try:
    manager.load(repo_id=repo)
except RuntimeError as e:
    if "already in progress" in str(e):
        wait_for_load_completion(manager)   # poll status, then retry once
        manager.load(repo_id=repo)
    else:
        raise

Prevention

When it happens

Trigger: Issuing a second load (or route-triggered model switch) while the first load's background thread is still downloading/building - e.g. the user clicks a second model while the first is still in load-progress, or an automation fires two loads concurrently.

Common situations: Impatient double-click in the Studio UI; an orchestrator retrying/switching models without waiting for the previous load to finish; a load that stalls on a slow download while the user picks a different model.

Related errors


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