invoke-ai/InvokeAI · error · NotAMatchError

model does not match Qwen Image LoRA heuristics

Error message

model does not match Qwen Image LoRA heuristics

What it means

NotAMatchError raised by LoRA_LyCORIS_QwenImage_Config._validate_looks_like_lora when the state dict fails the conjunctive Qwen Image Edit test: it must have transformer_blocks./transformer.transformer_blocks./lora_unet_transformer_blocks_ keys AND a LoRA suffix (lora_A/lora_B/lora_down/lora_up/dora_scale/lokr_w1/lokr_w2) AND must NOT contain Z-Image (diffusion_model.layers.), Krea-2 (text_fusion/txtfusion/time_mod_proj/attn.wq+attn.gate), or Flux (double_blocks/single_blocks/etc.) keys. Any failure of this combined condition rejects the file.

Source

Thrown at invokeai/backend/model_manager/configs/lora.py:858

        # text-fusion stage. Exclude them here so they route to LoRA_LyCORIS_Krea2_Config.
        has_krea2_keys = _has_krea2_lora_keys(state_dict)
        has_flux_keys = state_dict_has_any_keys_starting_with(
            state_dict,
            {
                "double_blocks.",
                "single_blocks.",
                "single_transformer_blocks.",
                "transformer.single_transformer_blocks.",
                "lora_unet_double_blocks_",
                "lora_unet_single_blocks_",
                "lora_unet_single_transformer_blocks_",
            },
        )

        if has_qwen_ie_keys and has_lora_suffix and not has_z_image_keys and not has_krea2_keys and not has_flux_keys:
            return

        raise NotAMatchError("model does not match Qwen Image LoRA heuristics")

    @classmethod
    def _get_base_or_raise(cls, mod: ModelOnDisk) -> BaseModelType:
        state_dict = mod.load_state_dict()
        has_qwen_ie_keys = state_dict_has_any_keys_starting_with(
            state_dict,
            {"transformer_blocks.", "transformer.transformer_blocks.", "lora_unet_transformer_blocks_"},
        )
        has_z_image_keys = state_dict_has_any_keys_starting_with(state_dict, {"diffusion_model.layers."})
        has_krea2_keys = _has_krea2_lora_keys(state_dict)
        has_flux_keys = state_dict_has_any_keys_starting_with(
            state_dict,
            {
                "double_blocks.",
                "single_blocks.",
                "single_transformer_blocks.",
                "transformer.single_transformer_blocks.",
                "lora_unet_double_blocks_",

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Determine which exclusions fired: if the file has diffusion_model.layers./double_blocks./Krea-2 keys, it belongs to another base — let the correct config claim it; the error may be an expected probe failure.
  2. For a real Qwen Image LoRA, update InvokeAI so newer trainer formats and exclusions are recognized.
  3. Verify file integrity — a truncated safetensors may have lost the lora_A/lora_B suffix keys; re-download.
  4. Re-export in Kohya (lora_unet_transformer_blocks_...) or diffusers PEFT format matching the expected prefixes/suffixes.
  5. Install with explicit base override (base=QwenImage) to bypass heuristics.

Example fix

// before: Qwen LoRA whose keys also include Flux single_blocks (ambiguous)
// after: strip the foreign keys before import
targeted = {k: v for k, v in sd.items() if not k.startswith(("single_blocks.", "double_blocks."))}
save_file(targeted, "qwen_lora.safetensors")
Defensive patterns

Strategy: validation

Validate before calling

sd = load_file("model.safetensors")
qwen_prefixes = ("transformer_blocks.", "transformer.transformer_blocks.", "lora_unet_transformer_blocks_")
lora_suffixes = ("lora_A.weight", "lora_B.weight", "lora_down.weight", "lora_up.weight",
                 "dora_scale", "lokr_w1", "lokr_w2")
excluded = ("diffusion_model.layers.", "double_blocks.", "single_blocks.",
            "single_transformer_blocks.", "transformer.single_transformer_blocks.")
ok = (any(k.startswith(qwen_prefixes) for k in sd)
      and any(k.endswith(lora_suffixes) for k in sd)
      and not any(k.startswith(excluded) for k in sd)
      and not any("text_fusion" in k or "txtfusion" in k or "time_mod_proj" in k for k in sd))
if not ok:
    print("Will not match Qwen Image LoRA heuristics")

Type guard

def is_qwen_image_lora_state_dict(state_dict: dict) -> bool:
    qwen = ("transformer_blocks.", "transformer.transformer_blocks.", "lora_unet_transformer_blocks_")
    lora = ("lora_A.weight", "lora_B.weight", "lora_down.weight", "lora_up.weight", "dora_scale", "lokr_w1", "lokr_w2")
    flux_or_z = ("diffusion_model.layers.", "double_blocks.", "single_blocks.", "single_transformer_blocks.")
    return (any(k.startswith(qwen) for k in state_dict)
            and any(k.endswith(lora) for k in state_dict)
            and not any(k.startswith(flux_or_z) for k in state_dict))

Try / catch

try:
    config = LoRA_LyCORIS_QwenImage_Config.from_model_on_disk(mod, {})
except NotAMatchError as e:
    logger.warning("Qwen Image heuristic rejected file: %s", e)
    config = None  # allow other config classes (Flux/Krea2/ZImage) to claim it

Prevention

When it happens

Trigger: from_model_on_disk probes a candidate Qwen Image LoRA and either the transformer_blocks prefixes are absent, no LoRA/LoKR suffix exists, or the file actually belongs to Z-Image, Krea-2, or Flux (excluded to prevent false routing).

Common situations: Importing a Flux LoRA whose transformer_blocks keys triggered the Qwen candidate (correctly rejected), a Krea-2 LoRA carrying transformer.transformer_blocks keys, a merged model with residual LoRA keys, or a genuinely broken/truncated Qwen LoRA missing its lora_A/lora_B weights.

Related errors


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