invoke-ai/InvokeAI · error · ValueError

Layer '{layer_name}' does not match the expected pattern for

Error message

Layer '{layer_name}' does not match the expected pattern for FLUX LoRA weights.

What it means

lora_model_from_flux_kohya_state_dict partitions a Kohya FLUX LoRA state dict into transformer, CLIP, and T5 groups by key prefix (lora_unet_, lora_te1_, lora_te2_). Any top-level layer name starting with none of these prefixes raises ValueError. The LoRA file contains keys outside the Kohya FLUX convention.

Source

Thrown at invokeai/backend/patches/lora_conversions/flux_kohya_lora_conversion_utils.py:87

            grouped_state_dict[layer_name] = {}
        grouped_state_dict[layer_name][param_name] = value

    # Split the grouped state dict into transformer, CLIP, and T5 state dicts.
    transformer_grouped_sd: dict[str, dict[str, torch.Tensor]] = {}
    clip_grouped_sd: dict[str, dict[str, torch.Tensor]] = {}
    t5_grouped_sd: dict[str, dict[str, torch.Tensor]] = {}
    for layer_name, layer_state_dict in grouped_state_dict.items():
        if layer_name.startswith("lora_unet"):
            # Skip the final layer. This is incompatible with current model definition.
            if layer_name.startswith("lora_unet_final_layer"):
                continue
            transformer_grouped_sd[layer_name] = layer_state_dict
        elif layer_name.startswith("lora_te1"):
            clip_grouped_sd[layer_name] = layer_state_dict
        elif layer_name.startswith("lora_te2"):
            t5_grouped_sd[layer_name] = layer_state_dict
        else:
            raise ValueError(f"Layer '{layer_name}' does not match the expected pattern for FLUX LoRA weights.")

    # Convert the state dicts to the InvokeAI format.
    transformer_grouped_sd = _convert_flux_transformer_kohya_state_dict_to_invoke_format(transformer_grouped_sd)
    clip_grouped_sd = _convert_flux_clip_kohya_state_dict_to_invoke_format(clip_grouped_sd)
    t5_grouped_sd = _convert_flux_t5_kohya_state_dict_to_invoke_format(t5_grouped_sd)

    # Create LoRA layers.
    layers: dict[str, BaseLayerPatch] = {}
    for model_prefix, grouped_sd in [
        (FLUX_LORA_TRANSFORMER_PREFIX, transformer_grouped_sd),
        (FLUX_LORA_CLIP_PREFIX, clip_grouped_sd),
        (FLUX_LORA_T5_PREFIX, t5_grouped_sd),
    ]:
        for layer_key, layer_state_dict in grouped_sd.items():
            layers[model_prefix + layer_key] = any_lora_layer_from_state_dict(layer_state_dict)

    # Create and return the LoRAModelRaw.
    return ModelPatchRaw(layers=layers)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Check the failing layer_name's prefix; if it's not a FLUX LoRA, use the correct converter/loader for the base model family.
  2. Rename or strip the unexpected key if it's an extraneous entry (e.g. preview/metadata tensors leaking into the state dict).
  3. Regenerate the LoRA with a FLUX-capable trainer version that uses lora_unet_/lora_te1_/lora_te2_ prefixes.
Defensive patterns

Strategy: validation

Validate before calling

bad = [k for k in state_dict if not k.startswith(("lora_unet_", "lora_te1_", "lora_te2_"))]
assert not bad, f"non-FLUX-kohya keys present: {bad[:5]}"

Type guard

def is_flux_kohya_key(k: str) -> bool:
    return k.startswith(("lora_unet_", "lora_te1_", "lora_te2_"))

Try / catch

try:
    lora = lora_model_from_flux_kohya_state_dict(sd, model)
except ValueError as e:
    logger.error("Kohya FLUX LoRA has unexpected layer: %s", e)
    lora = None

Prevention

When it happens

Trigger: Loading a Kohya-format file where a layer key has an unexpected prefix (e.g. 'lora_te' from a single-text-encoder SD-style LoRA, 'lora_unet' misspelled, or SDXL/SD1.5 LoRA keys) passed to lora_model_from_flux_kohya_state_dict.

Common situations: Trying to load a Stable Diffusion / SDXL Kohya LoRA as a FLUX LoRA; a trainer emitting a new prefix convention; corrupted key names from manual renaming.

Related errors


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