invoke-ai/InvokeAI · error · ValueError

LoRA '{lora_key}' targets Wan {lora_variant.value.upper()} m

Error message

LoRA '{lora_key}' targets Wan {lora_variant.value.upper()} models, but the transformer is a {main_variant.value} model. A14B and 5B LoRAs are not interchangeable.

What it means

_assert_lora_variant_matches_main compares the LoRA's variant against the main transformer's variant and rejects mixes between 5B (TI2V-5B) and A14B lineages, because their architectures (and thus LoRA weight shapes) are not interchangeable. When both variants are known and one is 5B while the other is not, a ValueError naming both variants is raised.

Source

Thrown at invokeai/app/invocations/wan_lora_loader.py:70

            f"base={getattr(config_base, 'value', config_base)})."
        )


def _assert_lora_variant_matches_main(lora_config: object, main_config: object, lora_key: str) -> None:
    """Reject an A14B LoRA wired against a 5B main (and vice versa).

    A mismatch otherwise crashes deep in the layer patcher mid-denoise with an opaque
    tensor-shape error, after minutes of model loading. Skips silently when either
    variant is unrecorded (e.g. a LoRA whose targeted layers don't pin the inner dim).
    """
    lora_variant = getattr(lora_config, "variant", None)
    main_variant = getattr(main_config, "variant", None)
    if lora_variant is None or main_variant is None:
        return
    lora_is_5b = lora_variant == WanLoRAVariantType.Wan5B
    main_is_5b = main_variant == WanVariantType.TI2V_5B
    if lora_is_5b != main_is_5b:
        raise ValueError(
            f"LoRA '{lora_key}' targets Wan {lora_variant.value.upper()} models, but the "
            f"transformer is a {main_variant.value} model. A14B and 5B LoRAs are not interchangeable."
        )


def _correct_inert_low_routing(
    context: InvocationContext, main_config: object, lora_key: str, to_primary: bool, to_low_noise: bool
) -> tuple[bool, bool]:
    """Re-point a low-only routing at the primary list when the main is TI2V-5B.

    TI2V-5B is single-transformer: the denoise path only ever reads the primary LoRA
    list, so a LoRA routed low-only has no effect at all and the node still reports
    success. There is no ambiguity about what to do instead — the model has exactly one
    transformer — so correct the routing rather than merely warning about it.

    This is the backstop for the probe-side pin in ``LoRA_LyCORIS_Wan_Config``, which
    can only suppress the expert tag when it managed to detect the variant.
    ``detect_wan_lora_variant`` reads the inner dim off an ``attn1.to_q`` LoRA pair, so

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Use a LoRA whose variant matches the transformer: 5B LoRA only with TI2V-5B, A14B LoRA only with A14B.
  2. Check the LoRA card/README for the target Wan variant before downloading.
  3. If variant metadata is missing (check silently passes), verify compatibility manually or retrain/export the LoRA for the right variant.
  4. Keep separate workflows for Wan 2.1 A14B and Wan 2.2 TI2V-5B so LoRA lists don't mix.

Example fix

// before
transformer = load("wan2.1-a14b")
lora = load_lora("wan22-ti2v-5b-lora")
out = wan_lora_loader(loras=[lora], transformer=transformer)  # ValueError
// after
transformer = load("wan2.2-ti2v-5b")
lora = load_lora("wan22-ti2v-5b-lora")
out = wan_lora_loader(loras=[lora], transformer=transformer)
Defensive patterns

Strategy: validation

Validate before calling

lora_cfg = get_lora_config(key)
main_cfg = get_main_config(transformer)
lv, mv = getattr(lora_cfg, 'variant', None), getattr(main_cfg, 'variant', None)
if lv is not None and mv is not None:
    l5, m5 = (lv == WanLoRAVariantType.Wan5B), (mv == WanVariantType.TI2V_5B)
    if l5 != m5:
        raise ValueError(f"LoRA variant {lv} incompatible with transformer variant {mv}")

Type guard

def lora_matches_main(lora_variant, main_variant) -> bool:
    if lora_variant is None or main_variant is None:
        return True
    return (lora_variant == WanLoRAVariantType.Wan5B) == (main_variant == WanVariantType.TI2V_5B)

Try / catch

try:
    out = node.invoke(context)
except ValueError as e:
    if "not interchangeable" in str(e):
        loras = filter_loras_by_variant(loras, main_variant)
        out = replace(node, loras=loras).invoke(context)
    else:
        raise

Prevention

When it happens

Trigger: Loading a Wan 5B LoRA into an A14B transformer, or an A14B LoRA into a TI2V-5B transformer, via wan_lora_loader.invoke(), when both configs expose variant fields.

Common situations: Downloading a LoRA trained for Wan 2.2 TI2V-5B and applying it to Wan 2.1 A14B; ambiguous LoRA names like 'wan-lora' hiding the variant; collections mixing 2.1 and 2.2 LoRAs.

Related errors


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