{"record":{"id":"b02a1fa7bcfad28a","repo":"invoke-ai/InvokeAI","slug":"unrecognized-model-extension-path-suffix","errorCode":null,"errorMessage":"Unrecognized model extension: {path.suffix}","messagePattern":"Unrecognized model extension: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/model_on_disk.py","lineNumber":148,"sourceCode":"                if scan_result.scan_err:\n                    if get_config().unsafe_disable_picklescan:\n                        logger.warning(\n                            f\"Error scanning the model at {path.stem} for malware, but picklescan is disabled. \"\n                            \"Proceeding with caution.\"\n                        )\n                    else:\n                        raise RuntimeError(f\"Error scanning the model at {path.stem} for malware. Aborting import.\")\n                checkpoint = torch.load(path, map_location=\"cpu\")\n                assert isinstance(checkpoint, dict)\n            elif path.suffix.endswith(\".gguf\"):\n                checkpoint = gguf_sd_loader(path, compute_dtype=torch.float32)\n            elif path.suffix.endswith(\".safetensors\"):\n                if _is_sdnq_safetensors(path):\n                    checkpoint = sdnq_sd_loader(path, compute_dtype=torch.float32)\n                else:\n                    checkpoint = safetensors.torch.load_file(path)\n            else:\n                raise ValueError(f\"Unrecognized model extension: {path.suffix}\")\n\n        state_dict = checkpoint.get(\"state_dict\", checkpoint)\n\n        # Normalize PEFT named-adapter keys (e.g. `lora_A.default.weight` → `lora_A.weight`).\n        # Pattern is LoRA-specific, so this is a no-op for non-LoRA state dicts.\n        from invokeai.backend.patches.lora_conversions.peft_adapter_utils import normalize_peft_adapter_names\n\n        state_dict = normalize_peft_adapter_names(state_dict)\n\n        self._state_dict_cache[path] = state_dict\n        return state_dict\n\n    def resolve_weight_file(self, path: Optional[Path] = None) -> Path:\n        if not path:\n            weight_files = list(self.weight_files())\n            match weight_files:\n                case []:\n                    raise ValueError(\"No weight files found for this model\")","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/model_on_disk.py#L130-L166","documentation":"load_state_dict dispatches on the weight file's extension: it supports pickle formats (.ckpt/.bin/.pt/.pth etc.), .gguf, and .safetensors. Any other suffix raises this ValueError because the loader has no reader for it. It's a fail-fast against silently loading garbage.","triggerScenarios":"resolve_weight_file picked (or path= pointed at) a file whose suffix is none of the supported ones — e.g. .json (model_index.json), .txt, .index.json, .onnx, .msgpack, .pth.tar — and load_state_dict was called on it.","commonSituations":"Repos containing multiple files where the single weight file auto-detection grabbed a config/README; single-file checkpoints shipped as .tar archives; ONNX or other framework formats dropped into a diffusers-style folder; files whose real extension was mangled during download.","solutions":["Pass the correct weight file explicitly: load_state_dict(path=Path('model.safetensors')) instead of letting auto-detection choose.","Check the model directory listing and pick the actual weights file (.safetensors/.gguf/.ckpt/.pt/.pth/.bin).","If the file is a tar/zip archive, extract it first and import the extracted checkpoint.","If the suffix is mangled (e.g. 'model.safetensors.download'), rename it to the correct extension after verifying the download.","For genuinely unsupported formats (onnx, msgpack), convert the weights to safetensors before importing."],"exampleFix":"// before\nmod = ModelOnDisk(repo_dir)\nsd = mod.load_state_dict()  # picked config.json\n// after\nmod = ModelOnDisk(repo_dir)\nsd = mod.load_state_dict(path=repo_dir / 'diffusion_pytorch_model.safetensors')","handlingStrategy":"validation","validationCode":"from pathlib import Path\nSUPPORTED = {'.safetensors', '.gguf', '.ckpt', '.pt', '.pth', '.bin'}\ndef has_supported_weight(path: Path) -> bool:\n    return path.suffix in SUPPORTED","typeGuard":"def is_supported_weight_file(p: object) -> bool:\n    from pathlib import Path\n    return isinstance(p, Path) and p.suffix in {\n        '.safetensors', '.gguf', '.ckpt', '.pt', '.pth', '.bin'}","tryCatchPattern":"try:\n    sd = mod.load_state_dict(path)\nexcept ValueError as e:\n    if str(e).startswith('Unrecognized model extension'):\n        logger.error(f'{e} — pick a .safetensors/.gguf/.ckpt/.pt/.pth/.bin file explicitly.')\n    raise","preventionTips":["Always pass an explicit weight file path instead of relying on auto-detection in mixed-file repos","Exclude config/index/readme files from weight-file candidates before choosing one","Extract tar/zip archives before importing checkpoints","Convert onnx/msgpack/other-format weights to safetensors before import"],"tags":["model-loading","file-format","validation","unsupported-extension"],"backgroundTag":"unsupported-model-file-extension","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}