{"record":{"id":"542d916c6093c2e1","repo":"invoke-ai/InvokeAI","slug":"model-does-not-look-like-a-qwen-image-edit-lora","errorCode":null,"errorMessage":"model does not look like a Qwen Image Edit LoRA","messagePattern":"model does not look like a Qwen Image Edit LoRA","errorType":"exception","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/lora.py","lineNumber":884,"sourceCode":"        )\n        has_z_image_keys = state_dict_has_any_keys_starting_with(state_dict, {\"diffusion_model.layers.\"})\n        has_krea2_keys = _has_krea2_lora_keys(state_dict)\n        has_flux_keys = state_dict_has_any_keys_starting_with(\n            state_dict,\n            {\n                \"double_blocks.\",\n                \"single_blocks.\",\n                \"single_transformer_blocks.\",\n                \"transformer.single_transformer_blocks.\",\n                \"lora_unet_double_blocks_\",\n                \"lora_unet_single_blocks_\",\n                \"lora_unet_single_transformer_blocks_\",\n            },\n        )\n\n        if has_qwen_ie_keys and not has_z_image_keys and not has_krea2_keys and not has_flux_keys:\n            return BaseModelType.QwenImage\n        raise NotAMatchError(\"model does not look like a Qwen Image Edit LoRA\")\n\n\ndef _has_krea2_lora_keys(state_dict: dict[str | int, Any]) -> bool:\n    \"\"\"True if the state dict targets Krea-2's distinctive modules.\n\n    Covers both the diffusers naming (``text_fusion`` / ``time_mod_proj``) and the native/ComfyUI naming\n    (``txtfusion``, or the gated attention ``attn.wq`` + ``attn.gate`` unique to Krea-2's single-stream\n    blocks) so native-format LoRAs are recognized as Krea-2 rather than falling through to another base.\n    \"\"\"\n    str_keys = [k for k in state_dict.keys() if isinstance(k, str)]\n    if any((\"text_fusion\" in k or \"txtfusion\" in k or \"time_mod_proj\" in k) for k in str_keys):\n        return True\n    # Native gated attention identifies a transformer-only Krea-2 LoRA that lacks the text-fusion stage.\n    return any(\".attn.wq.\" in k for k in str_keys) and any(\".attn.gate.\" in k for k in str_keys)\n\n\n# Each LoRA weight half must be accompanied by its partner half. An orphaned half installs successfully\n# but crashes later during LoRA conversion, so we reject it at identification time.","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/lora.py#L866-L902","documentation":"InvokeAI probes every incoming LoRA file with per-format config classes, each of which implements _get_base_or_raise to decide which base model the weights target. The Qwen Image Edit LoRA config returns BaseModelType.QwenImage only when the state dict has qwen-ie keys AND has no z-image, krea2, or flux keys; otherwise it raises NotAMatchError with this message. It is a heuristic key-sniffing rejection, not a corruption or I/O problem.","triggerScenarios":"Installing a LoRA via the model manager (from_model_on_disk -> _validate_base -> _get_base_or_raise) whose state dict either lacks the distinctive lora_unet_single_transformer_blocks_-style qwen-ie key prefixes, or has them alongside keys that also match z-image/krea2/flux heuristics (the guard `has_qwen_ie_keys and not has_z_image_keys and not has_krea2_keys and not has_flux_keys` fails).","commonSituations":"Downloading a LoRA trained for a different DiT (Flux, Z-Image, Krea-2) and pointing InvokeAI at it expecting auto-detection; multi-base merged/transition LoRAs whose key set overlaps several formats; renamed/re-packed files where the qwen-ie key prefixes were stripped; a newer InvokeAI key-naming scheme not covered by the installed version's heuristics.","solutions":["Verify the LoRA was actually trained for Qwen Image Edit; check the source page or peek at state-dict key prefixes (safetensors.safe_open -> keys()).","Inspect the file's keys for flux/z-image/krea2 markers that make the probe ambiguous; if present, the file belongs to another format's config class and should be installed as that type.","Manually set the base model / config type in the model manager UI or API instead of relying on auto-probe.","Update InvokeAI; key-heuristic tables are extended in newer releases to recognize more Qwen Image Edit LoRA packagings."],"exampleFix":"// before: auto-probe of a Flux/qwen hybrid file raises\ninstaller.install(path=\"mixed_lora.safetensors\")\n// after: pre-check keys and route manually\nfrom safetensors import safe_open\nwith safe_open(\"mixed_lora.safetensors\", framework=\"pt\") as f:\n    keys = list(f.keys())\nhas_qwen = any(\"lora_unet_single_transformer_blocks_\" in k for k in keys)\nhas_flux = any(\"transformer.\" in k or \"flux\" in k.lower() for k in keys)\nif has_qwen and not has_flux:\n    installer.install(path=\"mixed_lora.safetensors\")\nelse:\n    installer.install(path=\"mixed_lora.safetensors\", config=ModelVariant(flux_lora_config))","handlingStrategy":"validation","validationCode":"from safetensors import safe_open\n\ndef probe_qwen_ie_lora(path):\n    with safe_open(path, framework=\"pt\") as f:\n        ks = list(f.keys())\n    has_qwen = any(\"lora_unet_single_transformer_blocks_\" in k for k in ks)\n    has_z_image = any(\"z_image\" in k.lower() for k in ks)\n    has_krea2 = any(\"text_fusion\" in k or \"time_mod_proj\" in k for k in ks)\n    has_flux = any(\"double_blocks\" in k or \"single_blocks\" in k for k in ks)\n    return has_qwen and not (has_z_image or has_krea2 or has_flux)\n\nassert probe_qwen_ie_lora(\"model.safetensors\"), \"file will be rejected as a Qwen Image Edit LoRA\"","typeGuard":"def is_qwen_ie_lora_state_dict(keys: list[str]) -> bool:\n    has_qwen = any(\"lora_unet_single_transformer_blocks_\" in k for k in keys)\n    other = any(s in k.lower() for k in keys for s in (\"z_image\", \"text_fusion\", \"time_mod_proj\", \"double_blocks\", \"single_blocks\"))\n    return has_qwen and not other","tryCatchPattern":"from invokeai.backend.model_manager.configs.lora import NotAMatchError\ntry:\n    installer.install(path=\"model.safetensors\")\nexcept NotAMatchError as e:\n    if \"Qwen Image Edit LoRA\" in str(e):\n        log.warning(\"not a Qwen IE LoRA: %s — inspect keys and pick the right base\", e)\n        installer.install(path=\"model.safetensors\", base=detect_base_manually(\"model.safetensors\"))\n    else:\n        raise","preventionTips":["Always check the training base stated on the download page before installing a LoRA.","Pre-flight the state-dict key prefixes with safetensors.safe_open before handing the file to the installer.","Keep InvokeAI updated so heuristic key tables cover current LoRA packagings.","Avoid merged multi-base LoRA files; they trigger cross-format ambiguity in every probe."],"tags":["invokeai","model-manager","lora","qwen-image","not-a-match","model-install"],"backgroundTag":"lora-not-a-match","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}