{"record":{"id":"f86de3581206a455","repo":"unslothai/unsloth","slug":"cn-fs-reason","errorCode":null,"errorMessage":"{_cn_fs.reason}","messagePattern":"\\{_cn_fs\\.reason\\}","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/inference/diffusion.py","lineNumber":4838,"sourceCode":"        fam = state.family\n        pipe_cls_name = getattr(fam, \"controlnet_pipeline_class\", None)\n        model_cls_name = getattr(fam, \"controlnet_model_class\", None)\n        if not pipe_cls_name or not model_cls_name:\n            raise ValueError(f\"ControlNet is not supported for the '{fam.name}' model family.\")\n        import diffusers\n\n        cn_model = self._cn_models.get(resolved_cn.id)\n        if cn_model is None:\n            if cancel.is_set():\n                raise RuntimeError(DIFFUSION_CANCELLED_MSG)\n            # resolve_controlnet accepts a bare owner/name without the trust gate and from_pretrained would execute a malicious\n            # pickle, so run the same Hub malware preflight. It fails OPEN, so a remote repo also forces safetensors below.\n            remote_cn = not getattr(resolved_cn, \"is_local\", False)\n            if remote_cn:\n                from utils.security import evaluate_file_security\n                _cn_fs = evaluate_file_security(resolved_cn.path, hf_token = state.hf_token or None)\n                if _cn_fs.blocked:\n                    raise ValueError(_cn_fs.reason)\n            # Keep at most one ControlNet resident, else swapping ControlNets accumulates until OOM.\n            if self._cn_models or self._cn_pipes:\n                self._cn_models.clear()\n                self._cn_pipes.clear()\n                clear_gpu_cache()\n            import torch\n\n            # state.dtype is the display string (\"bfloat16\"), so pass the real dtype and avoid a float32 load.\n            cn_dtype = getattr(torch, str(state.dtype).replace(\"torch.\", \"\"), None)\n            # Force safetensors for an untrusted remote repo: if the Hub scan failed open, an embedded pickle would still deserialize.\n            cn_from_pretrained_kwargs: dict[str, Any] = {\"cache_dir\": hub_cache_dir()}\n            if remote_cn:\n                cn_from_pretrained_kwargs[\"use_safetensors\"] = True\n            cn_model = getattr(diffusers, model_cls_name).from_pretrained(\n                resolved_cn.path,\n                torch_dtype = cn_dtype,\n                token = state.hf_token or None,  # blank -> anonymous\n                **cn_from_pretrained_kwargs,","sourceCodeStart":4820,"sourceCodeEnd":4856,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/diffusion.py#L4820-L4856","documentation":"Raised when the Hub malware preflight (`evaluate_file_security` from utils.security) blocks the requested remote ControlNet repository. Because `resolve_controlnet` accepts a bare owner/name without the trust gate, `from_pretrained` on a malicious repo would execute a pickle; the same security scan used for model loads runs here. The ValueError carries the scanner's reason string, and the check applies only to remote (non-local) ControlNet paths.","triggerScenarios":"Requesting a generate() with a ControlNet id that resolves to a remote Hub repo which the security scan flags (`_cn_fs.blocked` is True), with `is_local` falsy so the remote branch runs. The reason text comes directly from the security evaluation result.","commonSituations":"Users pasting arbitrary owner/name ControlNet repos from the Hub; typosquatted or pickle-carrying repos caught by the scanner; organizational policies where the malware preflight denies unknown repos.","solutions":["Read the reason string: it states why the repo was blocked (e.g. suspicious pickle, unsafe serialization format).","Use a trusted/local ControlNet model file instead of the flagged remote repo.","Pick a known-safe safetensors ControlNet repo from the Hub.","Do not bypass the gate; report genuinely false positives to the scanner maintainers."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Trust only known ControlNet sources; check before generate\nif not is_trusted_cn_repo(cn_id):  # your allowlist / local-path policy\n    raise ValueError(f\"ControlNet repo '{cn_id}' is not trusted\")","typeGuard":"def is_safe_cn_source(cn) -> bool:\n    \"\"\"Local file, or remote repo pinned to safetensors-only artifacts.\"\"\"\n    return bool(getattr(cn, \"is_local\", False)) or getattr(cn, \"safetensors_only\", False)","tryCatchPattern":"try:\n    diffusion.generate(prompt=p, controlnet=cn)\nexcept ValueError as e:\n    if \"blocked\" in str(e).lower() or security_scanner_reason(e):\n        log_security_event(str(e)); choose_trusted_cn()\n    else:\n        raise","preventionTips":["Prefer safetensors-only ControlNet repos from known publishers.","Never bypass the malware preflight; it is the pickle-execution guard for remote repos.","Use local ControlNet files for curated, pre-scanned sets."],"tags":["diffusion","security","controlnet","huggingface","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}