unslothai/unsloth · error · ValueError
{exc}
Error message
{exc} What it means
A FileNotFoundError from resolve_controlnet (unknown ControlNet id not in the catalog) is re-raised as ValueError with the original message. The comment in source makes the intent explicit: the route maps ValueError to HTTP 400, so an unknown CN id surfaces as a client error rather than a bare 500.
Source
Thrown at studio/backend/core/inference/diffusion.py:5449
transformer_quant = state.transformer_quant,
):
raise ValueError(
"ControlNet is not supported for this model/quantisation on the "
"diffusers engine (needs a bf16 or bnb-4bit load of a family with a "
"ControlNet pipeline; not GGUF-via-diffusers or torchao fp8/int8)."
)
# Decode + preprocess the control image FIRST so a bad image 400s before any CN download, at the OUTPUT size.
src = decode_b64_image(cn_image_b64, mode = "RGB")
control_pil = diffusion_controlnet.preprocess_control(src, cn_type).resize(
(width, height), Image.LANCZOS
)
try:
resolved_cn = diffusion_controlnet.resolve_controlnet(
cn_id, family = state.family.name
)
except FileNotFoundError as exc:
# An unknown CN id -> 400, not 500 (the route maps ValueError).
raise ValueError(str(exc)) from exc
pipe = self._controlnet_pipe(state, resolved_cn, cancel)
workflow = "controlnet"
cn_scale, cn_gstart, cn_gend = cn_strength, cn_gs, cn_ge
# Flux Union CN selects its head by an integer control_mode; map the type.
cn_mode = diffusion_controlnet.union_control_mode(cn_id, cn_type)
# A prompt LIST batches plain text-to-image only: conditioned workflows take one image per call and a silent broadcast would pair every prompt with it.
if uniform_prompt(jobs) is None and workflow != "txt2img":
raise ValueError(
"A prompts list is supported for plain text-to-image only; the "
f"{workflow} workflow takes one prompt per call (seed lists still work)."
)
# Snap odd-sized inputs (and the mask) to a multiple of 16 where the OUTPUT size comes from the input image.
if init_pil is not None and workflow in ("img2img", "inpaint", "edit"):
# img2img/inpaint take output size from the upload, so bound the longest side to 2048 (a phone photo would OOM).
if workflow == "img2img":
# ...and bound Transform by the REQUESTED size too, so the Resolution
# control caps the output instead of being inert. img2img only: an
# inpaint payload is the canvas the mask was painted against (ExtendView on GitHub (pinned to 203007d190)
Solutions
- Use a ControlNet id from the current catalog (list available ControlNets via the app's catalog/registry endpoint or diffusion_controlnet catalog helpers).
- Check for typos in the repo id / spec id — full repo ids must match a curated entry exactly.
- If the CN was local ('source: local'), confirm it is still present on disk and re-registered.
Example fix
# before
controlnet=("xinsir-controlnet-sdxl-canny", img, "canny", 0.8, 0.0, 1.0) # typo'd id
# after
controlnet=("xinsir-controlnet-v1.1-sdxl-canny", img, "canny", 0.8, 0.0, 1.0) # exact catalog id Defensive patterns
Strategy: validation
Validate before calling
from core.inference.diffusion_controlnet import _catalog_by_id # or a public list endpoint
def valid_cn_id(spec_id: str) -> bool:
return spec_id in _catalog_by_id() or any(
e.repo_id == spec_id for e in getattr(__import__("core.inference.diffusion_controlnet", fromlist=["_CURATED"]), "_CURATED")
) Try / catch
try:
out = engine.generate(prompt=p, controlnet=(cn_id, img, t, s, gs, ge))
except ValueError as e:
if "ControlNet" in str(e) and "no longer present" not in str(e):
refresh_cn_catalog_and_repick() # 400-class: fix the id, don't retry the same one
else:
raise Prevention
- Populate CN pickers from the live catalog, not hardcoded ids.
- Re-validate stored CN ids after upgrading the app (catalogs drift between versions).
When it happens
Trigger: Passing a controlnet tuple whose id does not match any curated catalog entry or known repo id — e.g. a typo'd id, a repo that was never registered, or an entry removed from the catalog.
Common situations: Hand-writing API payloads with a ControlNet repo id from memory; catalogs drifting between versions so a previously valid id disappears; stale UI state referencing a deleted curated entry.
Related errors
- ControlNet '{spec_id}' is for {', '.join(entry.families)}, n
- ControlNet '{spec_id}' has no repo
- ControlNet is not supported for the '{fam.name}' model famil
- Diffusion generation was cancelled.
- {_cn_fs.reason}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/0347dad50fd27abe.
Report an issue: GitHub.