unslothai/unsloth · info · RuntimeError
Diffusion generation was cancelled.
Error message
Diffusion generation was cancelled.
What it means
A benign cancellation sentinel: while building the ControlNet pipeline, the per-generation `cancel` Event was already set before the ControlNet model download/load began, so `_controlnet_pipe` raises RuntimeError(DIFFUSION_CANCELLED_MSG) instead of doing wasted work. The cancel Event is set under `_lock` by unload() or a superseding load, so this indicates a model swap raced an in-flight generation request.
Source
Thrown at studio/backend/core/inference/diffusion.py:4830
def _controlnet_pipe(self, state: _LoadState, resolved_cn: Any, cancel: threading.Event) -> Any:
"""Build (once, cached) the family's diffusers ControlNet pipeline around the requested
ControlNet model. The ControlNet model is a small extra module loaded via from_pretrained
and cached by id; the pipeline is assembled with ``Pipeline.from_pipe(base,
controlnet=model)`` -- reusing the resident base modules at their loaded dtype (no reload,
no recast; torch_dtype=None for the same reason as _workflow_pipe). Raises a clear
ValueError when the family declares no ControlNet classes."""
fam = state.family
pipe_cls_name = getattr(fam, "controlnet_pipeline_class", None)
model_cls_name = getattr(fam, "controlnet_model_class", None)
if not pipe_cls_name or not model_cls_name:
raise ValueError(f"ControlNet is not supported for the '{fam.name}' model family.")
import diffusers
cn_model = self._cn_models.get(resolved_cn.id)
if cn_model is None:
if cancel.is_set():
raise RuntimeError(DIFFUSION_CANCELLED_MSG)
# resolve_controlnet accepts a bare owner/name without the trust gate and from_pretrained would execute a malicious
# pickle, so run the same Hub malware preflight. It fails OPEN, so a remote repo also forces safetensors below.
remote_cn = not getattr(resolved_cn, "is_local", False)
if remote_cn:
from utils.security import evaluate_file_security
_cn_fs = evaluate_file_security(resolved_cn.path, hf_token = state.hf_token or None)
if _cn_fs.blocked:
raise ValueError(_cn_fs.reason)
# Keep at most one ControlNet resident, else swapping ControlNets accumulates until OOM.
if self._cn_models or self._cn_pipes:
self._cn_models.clear()
self._cn_pipes.clear()
clear_gpu_cache()
import torch
# state.dtype is the display string ("bfloat16"), so pass the real dtype and avoid a float32 load.
cn_dtype = getattr(torch, str(state.dtype).replace("torch.", ""), None)
# Force safetensors for an untrusted remote repo: if the Hub scan failed open, an embedded pickle would still deserialize.View on GitHub (pinned to 203007d190)
Solutions
- Catch RuntimeError with the cancellation message and treat it as a no-op (the job was intentionally aborted).
- Re-issue the generate call after the new model finishes loading if the ControlNet result is still wanted.
- In orchestrating code, serialize load/unload and generate so cancels are observed before dispatching work.
Defensive patterns
Strategy: try-catch
Type guard
def is_cancel(exc: RuntimeError) -> bool:
return "cancelled" in str(exc).lower() Try / catch
try:
result = diffusion.generate(**params)
except RuntimeError as e:
if str(e) == DIFFUSION_CANCELLED_MSG: # or compare against the exported constant
return {"status": "cancelled"} # benign abort, not an error
raise Prevention
- Treat the cancellation message as control flow, not failure; never retry it automatically.
- Serialize model load/unload against generation dispatch in your orchestrator.
- Distinguish cancel sentinels from real failures by exact message or exception type.
When it happens
Trigger: A generate() call with ControlNet whose resolved ControlNet model is not cached; before `from_pretrained` starts, `cancel.is_set()` is True because unload() or a new load signaled this generation. The first check in the `cn_model is None` branch fires.
Common situations: User cancels or switches models right as a ControlNet job starts; a superseding load invalidates in-flight jobs; rapid UI interactions triggering unload during queued generations. Expected under normal concurrent use, not a bug.
Related errors
- A diffusion load is already in progress.
- ControlNet is not supported for the '{fam.name}' model famil
- {_cn_fs.reason}
- ControlNet currently combines with plain text-to-image only,
- ControlNet is not supported for this model/quantisation on t
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/0e84149848db0490.
Report an issue: GitHub.