{"record":{"id":"088addb053aee6a8","repo":"invoke-ai/InvokeAI","slug":"model-does-not-match-spandrelimagetoimage-heuristi","errorCode":null,"errorMessage":"model does not match SpandrelImageToImage heuristics","messagePattern":"model does not match SpandrelImageToImage heuristics","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"warning","filePath":"invokeai/backend/model_manager/configs/spandrel.py","lineNumber":54,"sourceCode":"\n        cls._validate_spandrel_loads_model(mod)\n\n        return cls(**override_fields)\n\n    @classmethod\n    def _validate_spandrel_loads_model(cls, mod: ModelOnDisk) -> None:\n        try:\n            # It would be nice to avoid having to load the Spandrel model from disk here. A couple of options were\n            # explored to avoid this:\n            # 1. Call `SpandrelImageToImageModel.load_from_state_dict(ckpt)`, where `ckpt` is a state_dict on the meta\n            #    device. Unfortunately, some Spandrel models perform operations during initialization that are not\n            #    supported on meta tensors.\n            # 2. Spandrel has internal logic to determine a model's type from its state_dict before loading the model.\n            #    This logic is not exposed in spandrel's public API. We could copy the logic here, but then we have to\n            #    maintain it, and the risk of false positive detections is higher.\n            SpandrelImageToImageModel.load_from_file(mod.path)\n        except Exception as e:\n            raise NotAMatchError(\"model does not match SpandrelImageToImage heuristics\") from e\n","sourceCodeStart":36,"sourceCodeEnd":55,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/spandrel.py#L36-L55","documentation":"`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__`).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check `error.__cause__` for the real spandrel load failure (unknown architecture vs corrupt file vs OOM)","If the model IS supported, upgrade the `spandrel` package — new architectures are added regularly","Move non-spandrel models (ControlNet, LoRA, checkpoints) out of folders scanned for upscalers or register them with the proper config class","Re-download the file if `__cause__` indicates a corrupt/truncated state dict"],"exampleFix":"# before: pip install spandrel==0.3.0 (new HAT variant unsupported)\n# after\npip install -U spandrel","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\nfrom spandrel import ImageModelDescriptor\ntry:\n    from spandrel_extra_arches import EXTRA_REGISTRY\n    from spandrel import ModelLoader\n    ModelLoader().load_model  # ensure spandrel importable\nexcept Exception:\n    pass\n\ndef spandrel_can_load(path: Path) -> bool:\n    from spandrel import ImageToImageModel\n    try:\n        ImageToImageModel.load_from_file(str(path))\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    cfg = SpandrelImageToImageConfig.from_model_on_disk(mod, override_fields)\nexcept NotAMatchError as e:\n    print(f\"not a spandrel-supported upscaler: {e.__cause__!r}\")\n    raise  # or route the file to its proper config class","preventionTips":["Keep spandrel (and spandrel_extra_arches if used) up to date","Only scan upscaler directories with spandrel-based configs","Check __cause__ to distinguish unknown-architecture from corrupt files"],"tags":["spandrel","upscaler","model-detection"],"backgroundTag":"model-not-supported","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}