invoke-ai/InvokeAI · error · NotAMatchError
Krea-2 LoRA has an incomplete lora_A/B (or lora_down/up) wei
Error message
Krea-2 LoRA has an incomplete lora_A/B (or lora_down/up) weight pair
What it means
Immediately after the heuristic pair check, the Krea-2 LoRA config runs _lora_weight_keys_are_all_paired to reject files containing an ORPHANED LoRA half: at least one valid layer plus a dangling lora_A/lora_B/lora_down/lora_up with no counterpart. Such a file would pass the initial check but crash later during LoRA conversion, so it is rejected up front with this NotAMatchError.
Source
Thrown at invokeai/backend/model_manager/configs/lora.py:1010
cls._validate_looks_like_lora(mod)
cls._validate_base(mod)
return cls(**override_fields)
@classmethod
def _validate_looks_like_lora(cls, mod: ModelOnDisk) -> None:
"""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:View on GitHub (pinned to 0b6a024f2f)
Solutions
- Re-download or re-export the LoRA; an orphaned half almost always means a corrupted or mis-merged file.
- Scan keys and find the layer(s) missing their sibling tensor (lora_A without lora_B, lora_down without lora_up), then remove the dangling keys or restore the missing tensor before installing.
- Re-merge the LoRA from its original training checkpoint so every layer is complete.
- If only one layer is broken, prune that layer entirely (the LoRA degrades gracefully) and reinstall.
Example fix
// before: orphaned half crashes conversion later
installer.install(path="krea2_lora.safetensors")
// after: detect and prune orphaned halves first
from safetensors import safe_open
with safe_open("krea2_lora.safetensors", framework="pt") as f:
ks = set(f.keys())
for base in {k.rsplit(".", 1)[0] for k in ks if any(k.endswith(s) for s in ("lora_A", "lora_B", "lora_down", "lora_up"))}:
pair = {f"{base}.lora_A", f"{base}.lora_B"} <= ks or {f"{base}.lora_down", f"{base}.lora_up"} <= ks
assert pair, f"orphaned LoRA half at {base}" Defensive patterns
Strategy: validation
Validate before calling
from safetensors import safe_open
def find_orphaned_lora_halves(path):
with safe_open(path, framework="pt") as f:
ks = set(f.keys())
suffixes = ("lora_A", "lora_B", "lora_down", "lora_up")
orphans = []
for k in (k for k in ks if any(k.endswith(s) for s in suffixes)):
base = k.rsplit(".", 1)[0]
if not ({f"{base}.lora_A", f"{base}.lora_B"} <= ks or {f"{base}.lora_down", f"{base}.lora_up"} <= ks):
orphans.append(base)
return orphans
assert not find_orphaned_lora_halves("krea2_lora.safetensors"), "file contains orphaned LoRA halves" Type guard
def lora_keys_all_paired(keys: set[str]) -> bool:
suffixes = ("lora_A", "lora_B", "lora_down", "lora_up")
for k in (k for k in keys if any(k.endswith(s) for s in suffixes)):
base = k.rsplit(".", 1)[0]
if not ({f"{base}.lora_A", f"{base}.lora_B"} <= keys or {f"{base}.lora_down", f"{base}.lora_up"} <= keys):
return False
return True Try / catch
try:
installer.install(path="krea2_lora.safetensors")
except NotAMatchError as e:
if "incomplete lora_A/B" in str(e):
log.error("orphaned LoRA half in file: %s", e)
cleaned = strip_orphaned_halves("krea2_lora.safetensors") # drop dangling keys or re-export
installer.install(path=cleaned)
else:
raise Prevention
- Never hand-edit or partially prune LoRA safetensors files; drop whole layers, not single tensors.
- Check merge/prune scripts so duplicate-key handling cannot drop one half of a pair.
- Re-download instead of repairing a suspicious file; orphaned halves usually mean a bad write.
- Run the pairing scan above as a pre-install gate in your model pipeline.
When it happens
Trigger: from_model_on_disk validation where the state dict contains one or more lora_A/lora_B (or lora_down/lora_up) keys whose sibling tensor is absent — e.g. a layer with only lora_down and no lora_up.
Common situations: Partially written or interrupted download; hand-edited or pruned LoRA exports that dropped one tensor to save space; merging scripts that concatenated key sets from two LoRAs and dropped duplicates incorrectly; corrupted safetensors headers after a failed save.
Related errors
- model does not match Krea-2 LoRA heuristics (no complete lor
- model does not look like a Krea-2 LoRA
- model does not look like a Qwen Image Edit LoRA
- model does not match Anima LoRA heuristics
- Unknown lora: {lora.lora.key}!
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/3287d13bdb7446c3.
Report an issue: GitHub.