invoke-ai/InvokeAI · info · NotAMatchError

transformer is SDNQ-quantized; use Main_SDNQ_Diffusers_ZImag

Error message

transformer is SDNQ-quantized; use Main_SDNQ_Diffusers_ZImage_Config

What it means

The plain Z-Image diffusers config raises NotAMatchError when the pipeline's `transformer/` folder is SDNQ-quantized, deferring to Main_SDNQ_Diffusers_ZImage_Config. Without this guard, both configs accept the same ZImagePipeline folder and identification may pick the plain one, which would mis-read packed uint8 weights as bf16 and crash at inference, and would also break the self-contained SDNQ path by forcing users to select separate VAE/Qwen3 sources.

Source

Thrown at invokeai/backend/model_manager/configs/main.py:1379

        raise_if_not_dir(mod)

        raise_for_override_fields(cls, override_fields)

        # This check implies the base type - no further validation needed.
        raise_for_class_name(
            common_config_paths(mod.path),
            {
                "ZImagePipeline",
            },
        )

        # Reject SDNQ-quantized pipelines so Main_SDNQ_Diffusers_ZImage_Config matches them instead.
        # Without this both configs accept the same ZImagePipeline folder and identification can
        # latch onto the plain diffusers one (which would then mis-read packed uint8 weights as bf16
        # and crash at inference). It also breaks the self-contained SDNQ path, since a pipeline
        # mis-identified as plain diffusers would force the user to select separate VAE/Qwen3 sources.
        if (mod.path / "transformer").is_dir() and _is_sdnq_folder(mod.path / "transformer"):
            raise NotAMatchError("transformer is SDNQ-quantized; use Main_SDNQ_Diffusers_ZImage_Config")

        variant = override_fields.pop("variant", None) or cls._get_variant_or_raise(mod)

        repo_variant = override_fields.pop("repo_variant", None) or cls._get_repo_variant_or_raise(mod)

        return cls(
            **override_fields,
            variant=variant,
            repo_variant=repo_variant,
        )

    @classmethod
    def _get_variant_or_raise(cls, mod: ModelOnDisk) -> ZImageVariantType:
        """Determine Z-Image variant from the scheduler config.

        Z-Image variants are distinguished by the scheduler shift value:
        - Turbo (distilled): shift = 3.0
        - Base (undistilled): shift = 6.0

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. No action required — the error routes the model to Main_SDNQ_Diffusers_ZImage_Config.
  2. If registration fails afterward, upgrade InvokeAI to a version that ships the SDNQ Z-Image config.
  3. For plain diffusers loading, use non-quantized Z-Image weights.
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def is_sdnq_zimage(folder: Path) -> bool:
    t = folder / "transformer"
    return t.is_dir() and ((t / "quantization_config.json").exists() or any(t.glob("*.sdnq")))

if is_sdnq_zimage(Path(model_dir)):
    expect_config = "Main_SDNQ_Diffusers_ZImage_Config"

Type guard

def is_sdnq_transformer(folder: Path) -> bool:
    return folder.is_dir() and (folder / "quantization_config.json").is_file()

Try / catch

try:
    cfg = Main_Diffusers_ZImage_Config.from_model_on_disk(mod)
except NotAMatchError:
    cfg = Main_SDNQ_Diffusers_ZImage_Config.from_model_on_disk(mod)

Prevention

When it happens

Trigger: Identifying a ZImagePipeline folder where `mod.path/transformer` is a directory detected as SDNQ-quantized by _is_sdnq_folder, via the scan/install path calling from_model_on_disk.

Common situations: Auto-registering an SDNQ-quantized Z-Image pipeline download; typically resolves as a correct SDNQ classification. Only surfaces as a problem if the SDNQ Z-Image config is absent (outdated InvokeAI).

Related errors


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