invoke-ai/InvokeAI · warning · NotAMatchError

model does not match SpandrelImageToImage heuristics

Error message

model does not match SpandrelImageToImage heuristics

What it means

`NotAMatchError` from `_validate_spandrel_loads_model`: `SpandrelImageToImageModel.load_from_file(mod.path)` threw, meaning spandrel could not load the file as one of its supported image-to-image architectures. Since spandrel's internal state_dict heuristics are not exposed, InvokeAI simply attempts a full load and converts any failure into a NotAMatchError (original exception chained as `__cause__`).

Source

Thrown at invokeai/backend/model_manager/configs/spandrel.py:54

        cls._validate_spandrel_loads_model(mod)

        return cls(**override_fields)

    @classmethod
    def _validate_spandrel_loads_model(cls, mod: ModelOnDisk) -> None:
        try:
            # It would be nice to avoid having to load the Spandrel model from disk here. A couple of options were
            # explored to avoid this:
            # 1. Call `SpandrelImageToImageModel.load_from_state_dict(ckpt)`, where `ckpt` is a state_dict on the meta
            #    device. Unfortunately, some Spandrel models perform operations during initialization that are not
            #    supported on meta tensors.
            # 2. Spandrel has internal logic to determine a model's type from its state_dict before loading the model.
            #    This logic is not exposed in spandrel's public API. We could copy the logic here, but then we have to
            #    maintain it, and the risk of false positive detections is higher.
            SpandrelImageToImageModel.load_from_file(mod.path)
        except Exception as e:
            raise NotAMatchError("model does not match SpandrelImageToImage heuristics") from e

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Check `error.__cause__` for the real spandrel load failure (unknown architecture vs corrupt file vs OOM)
  2. If the model IS supported, upgrade the `spandrel` package — new architectures are added regularly
  3. Move non-spandrel models (ControlNet, LoRA, checkpoints) out of folders scanned for upscalers or register them with the proper config class
  4. Re-download the file if `__cause__` indicates a corrupt/truncated state dict

Example fix

# before: pip install spandrel==0.3.0 (new HAT variant unsupported)
# after
pip install -U spandrel
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
from spandrel import ImageModelDescriptor
try:
    from spandrel_extra_arches import EXTRA_REGISTRY
    from spandrel import ModelLoader
    ModelLoader().load_model  # ensure spandrel importable
except Exception:
    pass

def spandrel_can_load(path: Path) -> bool:
    from spandrel import ImageToImageModel
    try:
        ImageToImageModel.load_from_file(str(path))
        return True
    except Exception:
        return False

Try / catch

try:
    cfg = SpandrelImageToImageConfig.from_model_on_disk(mod, override_fields)
except NotAMatchError as e:
    print(f"not a spandrel-supported upscaler: {e.__cause__!r}")
    raise  # or route the file to its proper config class

Prevention

When it happens

Trigger: Auto-probing a file that is not a spandrel-supported ESRGAN/HAT/SwinIR/Restormer/etc. model — e.g. a ControlNet, UNet, VAE, LoRA, or a spandrel-incompatible/corrupt checkpoint — during model install/import scanning.

Common situations: Pointing the import scanner at a mixed model folder, trying to load newer architectures not yet supported by the installed spandrel version, pickle-based `.pth` files with custom classes, corrupted downloads.

Related errors


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