unslothai/unsloth · error · FileNotFoundError
unknown ControlNet '{spec_id}': not a local model, catalog e
Error message
unknown ControlNet '{spec_id}': not a local model, catalog entry, or HF repo id What it means
resolve_controlnet() failed all three resolution paths: spec_id is not in the merged catalog (curated + local scan), not a curated repo_id, and does not match the strict 'owner/name' Hugging Face repo shape. The strict regex deliberately rejects anything that looks like a filesystem path so it can never reach from_pretrained.
Source
Thrown at studio/backend/core/inference/diffusion_controlnet.py:188
if entry.families and fam and fam not in {f.lower() for f in entry.families}:
raise ValueError(
f"ControlNet '{spec_id}' is for {', '.join(entry.families)}, not the loaded "
f"'{family}' model; pick a ControlNet built for this family."
)
if entry.source == "local":
path = entry.local_path or ""
if not path or not Path(path).is_dir():
raise FileNotFoundError(f"ControlNet '{spec_id}' is no longer present on disk")
return ResolvedControlNet(spec_id, path, is_local = True)
if not entry.repo_id:
raise ValueError(f"ControlNet '{spec_id}' has no repo")
return ResolvedControlNet(spec_id, entry.repo_id, is_local = False)
# A bare HF repo id (owner/name). STRICT shape so a filesystem-looking id can never reach from_pretrained.
if re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9_.-]*/[A-Za-z0-9][A-Za-z0-9_.-]*", spec_id):
return ResolvedControlNet(spec_id, spec_id, is_local = False)
raise FileNotFoundError(
f"unknown ControlNet '{spec_id}': not a local model, catalog entry, or HF repo id"
)
# Union ControlNet mode indices: a union model selects its head via an integer ``control_mode``.
_UNION_CONTROL_MODES: dict[str, int] = {
"canny": 0,
"tile": 1,
"depth": 2,
"blur": 3,
"pose": 4,
"gray": 5,
"lq": 6,
}
def union_control_mode(spec_id: str, control_type: str) -> Optional[int]:
"""The integer ``control_mode`` for a union ControlNet, or None.View on GitHub (pinned to 203007d190)
Solutions
- List valid ids with list_controlnets(family=...) and use one of those ids
- If you meant a Hugging Face model, pass the bare repo id exactly as 'owner/name' (no scheme, no host, no path separators beyond one '/')
- If you meant a local folder, place it in the scanned models directory with config.json plus weights so it appears in the catalog
- Routes should map this FileNotFoundError to a 400 so the client sees the message
Example fix
# before
resolve_controlnet("https://huggingface.co/lllyasviel/sd-controlnet-canny")
# after
resolve_controlnet("lllyasviel/sd-controlnet-canny") Defensive patterns
Strategy: validation
Validate before calling
import re
from studio.backend.core.inference.diffusion_controlnet import list_controlnets
HF_REPO = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.-]*/[A-Za-z0-9][A-Za-z0-9_.-]*")
def controlnet_id_valid(spec_id: str) -> bool:
if spec_id in {e.id for e in list_controlnets()}:
return True
return bool(HF_REPO.fullmatch(spec_id)) Try / catch
try:
resolved = resolve_controlnet(spec_id, family=fam)
except FileNotFoundError as e:
return bad_request(str(e)) # message lists all three accepted shapes Prevention
- Build ControlNet pickers from list_controlnets() plus validated 'owner/name' input only
- Strip URLs down to owner/name before calling resolve; never pass filesystem paths
- Map this FileNotFoundError to 400 in routes so clients see the guidance
When it happens
Trigger: Calling resolve_controlnet() with a typo'd id, a bare model name not present in the catalog, an absolute/relative path ('/data/cnet', './cnet', 'C:\\cnet'), or an id containing spaces or invalid characters. Paths and single-segment names fail the r'[A-Za-z0-9][A-Za-z0-9_.-]*/[A-Za-z0-9][A-Za-z0-9_.-]*' fullmatch.
Common situations: Client sends a local filesystem path expecting a direct load; stale UI offering an entry removed from the catalog; copy-paste of a repo URL (huggingface.co/owner/name) instead of the bare repo id; uppercase/underscore typos.
Related errors
- {_cn_fs.reason}
- Unknown control type {control_type!r} for a union ControlNet
- '{repo}' is gated on Hugging Face and this model cannot be d
- Non-GGUF diffusion loads are restricted to unsloth/* repos (
- '{repo_id}' is a single-file GGUF repo; load it with model_k
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/7163c2d63a9a8fb2.
Report an issue: GitHub.