invoke-ai/InvokeAI · error · ValueError

Model ' ' is not a Wan LoRA (resolved to type= , base= ).

Error message

Model '{lora_key}' is not a Wan LoRA (resolved to type={getattr(config_type, 'value', config_type)}, base={getattr(config_base, 'value', config_base)}).

What it means

_assert_is_wan_lora checks the model config the LoRA key actually resolves to and requires type == ModelType.LoRA and base == BaseModelType.Wan. This prevents non-Wan LoRAs (e.g. SDXL or Flux LoRAs) from being patched into a Wan transformer, which would either fail at patching time or silently waste minutes of loading. The error message includes the resolved type and base for diagnosis.

Solutions

  1. Point the loader at a model record that resolves to type=LoRA, base=Wan.
  2. Re-scan/import the LoRA in the Model Manager so its type and base are detected correctly.
  3. Remove non-Wan LoRAs from the Wan workflow's loader list.

Example fix

// before
lora = "sdxl-detail-lora"  # base=StableDiffusionXL
out = wan_lora_loader(loras=[lora], transformer=wan_transformer)  # ValueError
// after
lora = "wan2.1-speed-lora"  # type=LoRA, base=Wan
out = wan_lora_loader(loras=[lora], transformer=wan_transformer)
Defensive patterns

Strategy: validation

Validate before calling

cfg = context.models.get_config(lora_key)
if cfg is None or cfg.type is not ModelType.LoRA or cfg.base is not BaseModelType.Wan:
    raise ValueError(f"{lora_key} is not a Wan LoRA (type={getattr(cfg, 'type', None)}, base={getattr(cfg, 'base', None)})")

Type guard

def is_wan_lora(cfg) -> bool:
    return (getattr(cfg, 'type', None) is ModelType.LoRA
            and getattr(cfg, 'base', None) is BaseModelType.Wan)

Try / catch

try:
    out = node.invoke(context)
except ValueError as e:
    if "is not a Wan LoRA" in str(e):
        loras = [k for k in loras if is_wan_lora(get_config(k))]
        out = replace(node, loras=loras).invoke(context)
    else:
        raise

Prevention

When it happens

Trigger: Adding a LoRA whose model-manager record resolves to a non-LoRA type or a non-Wan base (e.g. a main model id, a SDXL LoRA, a Flux LoRA) to wan_lora_loader and calling invoke().

Common situations: Copy-pasting a wrong model ID into the LoRA field; the Model Manager record misconfigured (wrong type/base on import); reusing an image-model LoRA list node in a Wan workflow.

Related errors


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

Appendix: source

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

# single-transformer TI2V-5B main, ``_correct_inert_low_routing`` re-points it at
# the primary list, because that model has no low-noise expert and the alternative
# is to accept the LoRA and silently do nothing with it. ``both`` and ``high``
# always reach the primary list, so they are never affected.
WanLoRATarget = Literal["auto", "both", "high", "low"]


def _assert_is_wan_lora(lora_config: object, lora_key: str) -> None:
    """Reject an identifier whose *resolved* config is not a Wan LoRA.

    The identifier's own ``base``/``type`` fields are client-supplied and cannot be
    trusted: a hand-authored workflow can label any existing model key as a Wan LoRA
    and reach model patching (or fail minutes in, after expensive loading). Only the
    config the key actually resolves to is authoritative.
    """
    config_type = getattr(lora_config, "type", None)
    config_base = getattr(lora_config, "base", None)
    if config_type is not ModelType.LoRA or config_base is not BaseModelType.Wan:
        raise ValueError(
            f"Model '{lora_key}' is not a Wan LoRA (resolved to "
            f"type={getattr(config_type, 'value', config_type)}, "
            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

View on GitHub (pinned to 0b6a024f2f)