{"record":{"id":"584fdb9c78f6ccad","repo":"invoke-ai/InvokeAI","slug":"model-is-not-a-flux-2-lora","errorCode":null,"errorMessage":"model is not a FLUX.2 LoRA","messagePattern":"model is not a FLUX\\.2 LoRA","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/lora.py","lineNumber":707,"sourceCode":"    \"\"\"Model config for FLUX.2 (Klein) LoRA models in LyCORIS format.\"\"\"\n\n    base: Literal[BaseModelType.Flux2] = Field(default=BaseModelType.Flux2)\n    variant: Flux2VariantType | None = Field(default=None)\n\n    @classmethod\n    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:\n        raise_if_not_file(mod)\n        raise_for_override_fields(cls, override_fields)\n        cls._validate_looks_like_lora(mod)\n        cls._validate_base(mod)\n        override_fields.setdefault(\"variant\", _get_flux2_lora_variant(mod.load_state_dict()))\n        return cls(**override_fields)\n\n    @classmethod\n    def _get_base_or_raise(cls, mod: ModelOnDisk) -> BaseModelType:\n        if _get_flux_lora_format(mod) and _is_flux2_lora(mod):\n            return BaseModelType.Flux2\n        raise NotAMatchError(\"model is not a FLUX.2 LoRA\")\n\n\nclass LoRA_LyCORIS_ZImage_Config(LoRA_LyCORIS_Config_Base, Config_Base):\n    \"\"\"Model config for Z-Image LoRA models in LyCORIS format.\"\"\"\n\n    base: Literal[BaseModelType.ZImage] = Field(default=BaseModelType.ZImage)\n    variant: ZImageVariantType | None = Field(default=None)\n\n    @classmethod\n    def _validate_looks_like_lora(cls, mod: ModelOnDisk) -> None:\n        \"\"\"Z-Image LoRAs have different key patterns than SD/SDXL LoRAs.\n\n        Z-Image LoRAs use keys like:\n        - diffusion_model.layers.X.attention.to_k.lora_down.weight (DoRA format)\n        - diffusion_model.layers.X.attention.to_k.lora_A.weight (PEFT format)\n        - diffusion_model.layers.X.attention.to_k.dora_scale (DoRA scale)\n        - lora_unet__layers_X_attention_to_k.lora_down.weight (Kohya format)\n        \"\"\"","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/lora.py#L689-L725","documentation":"NotAMatchError raised by LoRA_LyCORIS_Flux2_Config._get_base_or_raise when the model is not simultaneously (a) in a recognized Flux LoRA format (Kohya, Diffusers, OneTrainer, AIToolkit, XLabs, etc. per _get_flux_lora_format) and (b) detected as a FLUX.2 (Klein) LoRA by _is_flux2_lora. This config class only claims files that are definitively FLUX.2 LoRAs; anything else falls through so another config class can match.","triggerScenarios":"from_model_on_disk is called on a file that reached the Flux2 config candidate during model scanning but either _get_flux_lora_format(mod) returns None (unrecognized LoRA key format) or _is_flux2_lora(mod) returns False (keys belong to FLUX.1, not FLUX.2).","commonSituations":"Importing a FLUX.1 LoRA that is being probed against the newer FLUX.2 config class, a Flux LoRA saved by an unlisted trainer (format markers not recognized), or a FLUX.2 LoRA repackaged with non-standard key names so _is_flux2_lora cannot identify it.","solutions":["This error is often benign during a scan — InvokeAI tries multiple config classes; verify whether the model was eventually matched by another config (e.g. LoRA_LyCORIS_FLUX_Config) before treating it as a failure.","If it is a FLUX.1 LoRA, no fix needed — it should match the FLUX (non-.2) config; ensure InvokeAI is up to date so routing works.","If it is a genuine FLUX.2 LoRA, update InvokeAI — newer versions recognize more trainer formats in _get_flux_lora_format.","Re-export the LoRA in Kohya or diffusers PEFT format so the format detector recognizes it.","Specify the base model explicitly via override fields during install to bypass auto-detection."],"exampleFix":"// before: ambiguous file left to auto-routing\ncls(**override_fields)\n// after: pin the base during install so the correct config claims it\nfrom_model_on_disk(mod, {\"base\": BaseModelType.Flux2})","handlingStrategy":"fallback","validationCode":"from invokeai.backend.model_manager.configs.lora import _get_flux_lora_format, _is_flux2_lora\n\nmod = ModelOnDisk(path)\nif not (_get_flux_lora_format(mod) and _is_flux2_lora(mod)):\n    print(\"File will not match the FLUX.2 LoRA config; expect other configs to claim it\")","typeGuard":"def is_flux2_lora_file(mod) -> bool:\n    return _get_flux_lora_format(mod) is not None and _is_flux2_lora(mod)","tryCatchPattern":"try:\n    config = LoRA_LyCORIS_Flux2_Config.from_model_on_disk(mod, override_fields)\nexcept NotAMatchError:\n    # Fall back to generic FLUX / LyCORIS routing; the scan continues with other configs\n    config = None","preventionTips":["Remember this config class is probed speculatively; treat single NotAMatchError as noise unless the model ends up unmatched.","Export FLUX.2 LoRAs in Kohya or diffusers PEFT format so _get_flux_lora_format recognizes them.","Don't rename Flux LoRA keys manually — the Flux1/Flux2 distinction depends on exact key structure.","Keep InvokeAI current; trainer format lists in _get_flux_lora_format grow with releases."],"tags":["lora","flux","model-import","format-detection","invokeai"],"backgroundTag":"unrecognized-model-format","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}