invoke-ai/InvokeAI · error · ValueError
Model '{lora_key}' is not a Wan LoRA (resolved to type={geta
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.
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.Wan5BView on GitHub (pinned to 0b6a024f2f)
Solutions
- Point the loader at a model record that resolves to type=LoRA, base=Wan.
- Re-scan/import the LoRA in the Model Manager so its type and base are detected correctly.
- 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
- Import LoRAs through the Model Manager so type/base are auto-detected.
- Inspect each LoRA record's type/base before adding to Wan workflows.
- Keep Wan LoRAs in a dedicated collection.
- Don't reuse image-model LoRA loader nodes for Wan.
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
- LoRA '{lora_key}' targets Wan {lora_variant.value.upper()} m
- LoRA "{lora_key}" already applied to transformer.
- Selected model provider '{model_config.provider_id}' does no
- LoRA '{lora_config.name}' is a {lora_variant.value} LoRA and
- LoRA "{lora_key}" already applied to transformer.
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/2109cf7cbba1b8e3.
Report an issue: GitHub.