invoke-ai/InvokeAI · error · NotAMatchError

model does not look like a Krea-2 LoRA

Error message

model does not look like a Krea-2 LoRA

What it means

The Krea-2 LoRA config's _get_base_or_raise returns BaseModelType.Krea2 only if _has_krea2_lora_keys finds Krea-2's distinctive modules in the state dict (text_fusion / time_mod_proj in diffusers naming, or the equivalent native/ComfyUI naming). If none of those key patterns match, it raises NotAMatchError with this message during base-model detection.

Source

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

        """Krea-2 LoRAs have keys like transformer.text_fusion.* / transformer.transformer_blocks.* with
        a lora_A/lora_B (or lora_down/lora_up) suffix. The text-fusion stage is unique to Krea-2."""
        state_dict = mod.load_state_dict()
        # Require a *complete* lora_A/B (or lora_down/up) pair, not merely any lora/dora suffix: a file with
        # only ``dora_scale`` and no A/B weights would pass a suffix check but fail later on missing weights.
        if not (_has_krea2_lora_keys(state_dict) and _has_complete_lora_pair(state_dict)):
            raise NotAMatchError(
                "model does not match Krea-2 LoRA heuristics (no complete lora_A/B or lora_down/up pair)"
            )
        # Reject a file with an orphaned LoRA half (a valid layer plus a dangling lora_A/B/down/up); it
        # would install here but fail later during LoRA conversion.
        if not _lora_weight_keys_are_all_paired(state_dict):
            raise NotAMatchError("Krea-2 LoRA has an incomplete lora_A/B (or lora_down/up) weight pair")

    @classmethod
    def _get_base_or_raise(cls, mod: ModelOnDisk) -> BaseModelType:
        if _has_krea2_lora_keys(mod.load_state_dict()):
            return BaseModelType.Krea2
        raise NotAMatchError("model does not look like a Krea-2 LoRA")


class LoRA_LyCORIS_Anima_Config(LoRA_LyCORIS_Config_Base, Config_Base):
    """Model config for Anima LoRA models in LyCORIS format."""

    base: Literal[BaseModelType.Anima] = Field(default=BaseModelType.Anima)

    @classmethod
    def _validate_looks_like_lora(cls, mod: ModelOnDisk) -> None:
        """Anima LoRAs use Kohya-style keys targeting Cosmos DiT blocks.

        Anima LoRAs have keys like:
        - lora_unet_blocks_0_cross_attn_k_proj.lora_down.weight (Kohya format)
        - diffusion_model.blocks.0.cross_attn.k_proj.lora_A.weight (diffusers PEFT format)
        - transformer.blocks.0.mlp.layer_0.lora_A.weight (Anima-only MLP layer)

        Uses the **strict** Cosmos-DiT detectors, which require an
        Anima-exclusive subcomponent name (``mlp``, ``adaln_modulation``, or

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Dump the state-dict keys (safetensors.safe_open -> keys()) and confirm which architecture the prefixes actually target.
  2. Install the LoRA under the correct base-model config (let another config class claim it, or select the type manually).
  3. If it really is a Krea-2 LoRA with unusual naming, update InvokeAI — the _has_krea2_lora_keys pattern list is expanded in newer releases.
  4. Rename/wrap the export to use the standard diffusers naming (transformer.text_fusion.*, transformer.transformer_blocks.*) so the heuristic matches.

Example fix

// before: relies on filename, probe rejects it
installer.install(path="my_krea_style_lora.safetensors")  # NotAMatchError
// after: check actual key prefixes and pick the right config
from safetensors import safe_open
with safe_open("my_krea_style_lora.safetensors", framework="pt") as f:
    ks = list(f.keys())
is_krea2 = any("text_fusion" in k or "time_mod_proj" in k for k in ks)
installer.install(path="my_krea_style_lora.safetensors",
                 base="krea2" if is_krea2 else detect_base_from_keys(ks))
Defensive patterns

Strategy: validation

Validate before calling

from safetensors import safe_open

def looks_like_krea2_lora(path):
    with safe_open(path, framework="pt") as f:
        ks = list(f.keys())
    return any("text_fusion" in k or "time_mod_proj" in k for k in ks)

if not looks_like_krea2_lora("model.safetensors"):
    print("not a Krea-2 LoRA; install under the correct base or update InvokeAI")

Type guard

def is_krea2_lora_state_dict(keys: list[str]) -> bool:
    return any("text_fusion" in k or "time_mod_proj" in k for k in keys)

Try / catch

try:
    installer.install(path="model.safetensors")
except NotAMatchError as e:
    if "does not look like a Krea-2 LoRA" in str(e):
        base = detect_base_from_keys(list_keys("model.safetensors"))
        installer.install(path="model.safetensors", base=base)
    else:
        raise

Prevention

When it happens

Trigger: Auto-probing a LoRA that has no transformer.text_fusion.*/transformer.transformer_blocks.* (or native-named equivalents) keys — i.e. any LoRA trained for another architecture that reaches the Krea-2 config class during format detection.

Common situations: Installing a Qwen/Flux/SDXL LoRA and expecting Krea-2; a Krea-2 LoRA exported with a key-naming scheme not yet covered by the installed InvokeAI version's heuristic; file renamed with 'krea' in the filename but weights actually target another base.

Related errors


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