unslothai/unsloth · error · ValueError
ControlNet '{spec_id}' has no repo
Error message
ControlNet '{spec_id}' has no repo What it means
resolve_controlnet() matched a catalog entry whose source is not 'local' but whose repo_id is empty, so there is nothing to download and nothing on disk to load. It is a guard against a malformed curated/catalog entry rather than a user input error.
Source
Thrown at studio/backend/core/inference/diffusion_controlnet.py:181
entry = _catalog_by_id().get(spec_id)
if entry is None:
# A curated entry named by its full repo id must still hit the family gate below, not slip through the bare-repo fallback.
entry = next((e for e in _CURATED if e.repo_id and e.repo_id == spec_id), None)
if entry is not None:
# A direct API call could send an entry for another family; reject it before any download.
fam = (family or "").strip().lower()
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,View on GitHub (pinned to 203007d190)
Solutions
- Fix the catalog entry: give it a valid Hugging Face repo_id (owner/name) or convert it to source='local' with a real local_path
- If you manage _CURATED in code, add an assertion/test that every non-local entry has a non-empty repo_id
- As a caller, catch ValueError and surface it as a configuration error rather than retrying
Example fix
# before ControlNetCatalogEntry(id="x", display_name="X", source="remote") # after ControlNetCatalogEntry(id="x", display_name="X", source="remote", repo_id="owner/x-controlnet")
Defensive patterns
Strategy: validation
Validate before calling
from studio.backend.core.inference.diffusion_controlnet import list_controlnets
bad = [e.id for e in list_controlnets() if e.source != "local" and not e.repo_id]
assert not bad, f"malformed catalog entries without repo_id: {bad}" Try / catch
try:
resolved = resolve_controlnet(spec_id, family=fam)
except ValueError as e:
log.error("catalog misconfigured for %s: %s", spec_id, e) # config defect, do not retry Prevention
- Assert at startup that every non-local catalog entry has a non-empty repo_id
- Review edits to the curated ControlNet list in CI
- Never retry this error; it is a data defect, not a transient condition
When it happens
Trigger: A catalog entry with source='remote' (or anything != 'local') and repo_id unset (None/'') reaching resolve_controlnet(); typically from editing the _CURATED list or injecting a custom entry with a missing repo_id.
Common situations: Hand-editing the curated ControlNet catalog and forgetting the repo_id field; a code change that constructs ControlNetCatalogEntry entries without repo_id; data migration that drops the field.
Related errors
- {exc}
- ControlNet '{spec_id}' is for {', '.join(entry.families)}, n
- 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/b32470b2f06b01e5.
Report an issue: GitHub.