{"record":{"id":"843d95ceb0f121f6","repo":"invoke-ai/InvokeAI","slug":"the-sdxl-lora-could-only-be-partially-converted-to","errorCode":null,"errorMessage":"The SDXL LoRA could only be partially converted to diffusers format. converted={converted_count}, not_converted={not_converted_count}","messagePattern":"The SDXL LoRA could only be partially converted to diffusers format\\. converted=(.+?), not_converted=(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/patches/lora_conversions/sdxl_lora_conversion_utils.py","lineNumber":57,"sourceCode":"            position = bisect.bisect_right(stability_unet_keys, search_key)\n            map_key = stability_unet_keys[position - 1]\n            # Now, check if the map_key *actually* matches the search_key.\n            if search_key.startswith(map_key):\n                new_key = full_key.replace(map_key, SDXL_UNET_STABILITY_TO_DIFFUSERS_MAP[map_key])\n                new_state_dict[new_key] = value\n                converted_count += 1\n            else:\n                new_state_dict[full_key] = value\n                not_converted_count += 1\n        elif full_key.startswith(\"lora_te1_\") or full_key.startswith(\"lora_te2_\"):\n            # The CLIP text encoders have the same keys in both Stability AI and diffusers formats.\n            new_state_dict[full_key] = value\n            continue\n        else:\n            raise ValueError(f\"Unrecognized SDXL LoRA key prefix: '{full_key}'.\")\n\n    if converted_count > 0 and not_converted_count > 0:\n        raise ValueError(\n            f\"The SDXL LoRA could only be partially converted to diffusers format. converted={converted_count},\"\n            f\" not_converted={not_converted_count}\"\n        )\n\n    return new_state_dict\n\n\n# code from\n# https://github.com/bmaltais/kohya_ss/blob/2accb1305979ba62f5077a23aabac23b4c37e935/networks/lora_diffusers.py#L15C1-L97C32\ndef _make_sdxl_unet_conversion_map() -> List[Tuple[str, str]]:\n    \"\"\"Create a dict mapping state_dict keys from Stability AI SDXL format to diffusers SDXL format.\"\"\"\n    unet_conversion_map_layer: list[tuple[str, str]] = []\n\n    for i in range(3):  # num_blocks is 3 in sdxl\n        # loop over downblocks/upblocks\n        for j in range(2):\n            # loop over resnets/attentions for downblocks\n            hf_down_res_prefix = f\"down_blocks.{i}.resnets.{j}.\"","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/patches/lora_conversions/sdxl_lora_conversion_utils.py#L39-L75","documentation":"convert_sdxl_keys_to_diffusers_format counts keys it successfully converted and keys it left unconverted. If both counts are positive, the file is a mix of recognized and unrecognized layouts; loading only part of it would silently leave some layers unapplied, so the converter raises instead.","triggerScenarios":"Calling convert_sdxl_keys_to_diffusers_format on a state dict where at least one key converted to diffusers format and at least one key matched no conversion rule (not_converted_count > 0 and converted_count > 0).","commonSituations":"LoRA files that bundle text-encoder keys plus keys from a different model family; merged LoRAs of mixed provenance; files where a subset of modules uses a legacy naming convention the converter does not handle.","solutions":["Log which keys were not converted and add/fix conversion rules or rename those keys to a supported format.","Split the state dict: convert/load the convertible portion with this loader and handle the rest separately.","Re-export the LoRA so all keys use one consistent SDXL naming convention."],"exampleFix":"// before: mixed file\n'lora_unet_blocks_0...': ok (converts)\n'weird_prefix_blocks_1...': not converted -> raises\n// after\n'lora_unet_blocks_0...': ok\n'lora_unet_blocks_1...': renamed to supported prefix","handlingStrategy":"validation","validationCode":"def is_fully_convertible(state_dict, convert_key) -> bool:\n    return all(convert_key(k) is not None for k in state_dict)","typeGuard":"def keys_are_homogeneous(state_dict: dict[str, object]) -> bool:\n    prefixes = {k.split('_', 2)[0] + '_' + k.split('_', 2)[1] if k.count('_') > 1 else k for k in state_dict if isinstance(k, str)}\n    return len({p for p in prefixes}) <= 3","tryCatchPattern":"try:\n    sd = convert_sdxl_keys_to_diffusers_format(state_dict)\nexcept ValueError as e:\n    if 'could only be partially converted' in str(e):\n        logger.error('Mixed-layout SDXL LoRA: %s', e)\n        # split state dict; convert/load each portion with the right loader\n    else:\n        raise","preventionTips":["Reject or split LoRA files that mix multiple naming conventions.","Log non-converting keys in a pre-pass so you know what will fail.","Re-export merged LoRAs with a single consistent key scheme."],"tags":["lora","sdxl","partial-conversion","mixed-format"],"backgroundTag":"unsupported-key-format","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}