invoke-ai/InvokeAI · error · ValueError

Unrecognized model extension: {path.suffix}

Error message

Unrecognized model extension: {path.suffix}

What it means

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.

Source

Thrown at invokeai/backend/model_manager/model_on_disk.py:148

                if scan_result.scan_err:
                    if get_config().unsafe_disable_picklescan:
                        logger.warning(
                            f"Error scanning the model at {path.stem} for malware, but picklescan is disabled. "
                            "Proceeding with caution."
                        )
                    else:
                        raise RuntimeError(f"Error scanning the model at {path.stem} for malware. Aborting import.")
                checkpoint = torch.load(path, map_location="cpu")
                assert isinstance(checkpoint, dict)
            elif path.suffix.endswith(".gguf"):
                checkpoint = gguf_sd_loader(path, compute_dtype=torch.float32)
            elif path.suffix.endswith(".safetensors"):
                if _is_sdnq_safetensors(path):
                    checkpoint = sdnq_sd_loader(path, compute_dtype=torch.float32)
                else:
                    checkpoint = safetensors.torch.load_file(path)
            else:
                raise ValueError(f"Unrecognized model extension: {path.suffix}")

        state_dict = checkpoint.get("state_dict", checkpoint)

        # Normalize PEFT named-adapter keys (e.g. `lora_A.default.weight` → `lora_A.weight`).
        # Pattern is LoRA-specific, so this is a no-op for non-LoRA state dicts.
        from invokeai.backend.patches.lora_conversions.peft_adapter_utils import normalize_peft_adapter_names

        state_dict = normalize_peft_adapter_names(state_dict)

        self._state_dict_cache[path] = state_dict
        return state_dict

    def resolve_weight_file(self, path: Optional[Path] = None) -> Path:
        if not path:
            weight_files = list(self.weight_files())
            match weight_files:
                case []:
                    raise ValueError("No weight files found for this model")

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Pass the correct weight file explicitly: load_state_dict(path=Path('model.safetensors')) instead of letting auto-detection choose.
  2. Check the model directory listing and pick the actual weights file (.safetensors/.gguf/.ckpt/.pt/.pth/.bin).
  3. If the file is a tar/zip archive, extract it first and import the extracted checkpoint.
  4. If the suffix is mangled (e.g. 'model.safetensors.download'), rename it to the correct extension after verifying the download.
  5. For genuinely unsupported formats (onnx, msgpack), convert the weights to safetensors before importing.

Example fix

// before
mod = ModelOnDisk(repo_dir)
sd = mod.load_state_dict()  # picked config.json
// after
mod = ModelOnDisk(repo_dir)
sd = mod.load_state_dict(path=repo_dir / 'diffusion_pytorch_model.safetensors')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
SUPPORTED = {'.safetensors', '.gguf', '.ckpt', '.pt', '.pth', '.bin'}
def has_supported_weight(path: Path) -> bool:
    return path.suffix in SUPPORTED

Type guard

def is_supported_weight_file(p: object) -> bool:
    from pathlib import Path
    return isinstance(p, Path) and p.suffix in {
        '.safetensors', '.gguf', '.ckpt', '.pt', '.pth', '.bin'}

Try / catch

try:
    sd = mod.load_state_dict(path)
except ValueError as e:
    if str(e).startswith('Unrecognized model extension'):
        logger.error(f'{e} — pick a .safetensors/.gguf/.ckpt/.pt/.pth/.bin file explicitly.')
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/b02a1fa7bcfad28a. Report an issue: GitHub.