{"record":{"id":"63ef697794ef64b4","repo":"invoke-ai/InvokeAI","slug":"cannot-force-both-direct-and-sidecar-patching","errorCode":null,"errorMessage":"Cannot force both direct and sidecar patching.","messagePattern":"Cannot force both direct and sidecar patching\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/patches/layer_patcher.py","lineNumber":163,"sourceCode":"                else:\n                    logger = InvokeAILogger.get_logger(LayerPatcher.__name__)\n                    logger.warning(\"Failed to find module for LoRA layer key: %s\", layer_key)\n                continue\n\n            # Decide whether to use direct patching or a sidecar patch.\n            # Direct patching is preferred, because it results in better runtime speed.\n            # Reasons to use sidecar patching:\n            # - The module is quantized, so the caller passed force_sidecar_patching=True.\n            # - The module already has sidecar patches.\n            # - The module is on the CPU (and we don't want to store a second full copy of the original weights on the\n            #   CPU, since this would double the RAM usage)\n            # NOTE: For now, we don't check if the layer is quantized here. We assume that this is checked in the caller\n            # and that the caller will set force_sidecar_patching=True if the layer is quantized.\n            # TODO(ryand): Handle the case where we are running without a GPU. Should we set a config flag that allows\n            # forcing full patching even on the CPU?\n            use_sidecar_patching = False\n            if force_direct_patching and force_sidecar_patching:\n                raise ValueError(\"Cannot force both direct and sidecar patching.\")\n            elif force_sidecar_patching:\n                use_sidecar_patching = True\n            elif LayerPatcher._is_any_part_of_layer_fp8(module):\n                # FP8 weights (e.g. a model loaded with fp8_storage layerwise casting) cannot be\n                # directly patched: _apply_model_layer_patch does an in-place add on the model weight,\n                # and CUDA has no add kernel for float8 (\"ufunc_add_CUDA not implemented for\n                # Float8_e4m3fn\"). Sidecar patching dequantizes to the compute dtype before any math,\n                # so it works regardless of the storage dtype. This takes precedence over\n                # force_direct_patching, since direct patching is simply not possible on fp8 weights.\n                use_sidecar_patching = True\n            elif force_direct_patching:\n                use_sidecar_patching = False\n            elif module.get_num_patches() > 0:\n                use_sidecar_patching = True\n            elif LayerPatcher._is_any_part_of_layer_on_cpu(module):\n                use_sidecar_patching = True\n\n            if use_sidecar_patching:","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/patches/layer_patcher.py#L145-L181","documentation":"apply_smart_model_patch() chooses between direct in-place layer patching and sidecar (out-of-place) patching. Forcing both simultaneously is contradictory — direct patching mutates weights in place while sidecar keeps originals intact — so ValueError is raised as an argument-validation guard.","triggerScenarios":"Calling apply_smart_model_patch(..., force_direct_patching=True, force_sidecar_patching=True) — directly or via wrappers like patch_unet whose config flags both modes (e.g. sequential-guidance-style direct patching enabled together with a sidecar-forcing quantized model).","commonSituations":"Config where both a quantized-model requirement (forces sidecar) and a feature requiring direct patching are enabled at once; custom patching code passing both flags defensively; refactoring that merged two patch call sites.","solutions":["Set only one of force_direct_patching / force_sidecar_patching to True.","If the layer is quantized (fp8/bnb), remove force_direct_patching — sidecar is required.","If you need direct patching (e.g. CPU without GPU), drop force_sidecar_patching and ensure the layer is not fp8.","Audit config flags (e.g. attention-patching options) that feed these booleans."],"exampleFix":"// before\npatcher.apply_smart_model_patch(model, 'unet', loras=loras, force_direct_patching=True, force_sidecar_patching=True)\n// after\npatcher.apply_smart_model_patch(model, 'unet', loras=loras, force_sidecar_patching=True)","handlingStrategy":"validation","validationCode":"if force_direct_patching and force_sidecar_patching:\n    raise ValueError('Pick one patching mode: direct (in-place) or sidecar (out-of-place)')\nif is_quantized(layer) and force_direct_patching:\n    raise ValueError('Quantized layers require sidecar patching')","typeGuard":"def patch_mode_is_valid(force_direct: bool, force_sidecar: bool) -> bool:\n    return not (force_direct and force_sidecar)","tryCatchPattern":"try:\n    apply_smart_model_patch(model, prefix, loras, force_direct_patching=fd, force_sidecar_patching=fs)\nexcept ValueError as e:\n    if 'Cannot force both' in str(e):\n        apply_smart_model_patch(model, prefix, loras, force_sidecar_patching=True)  # safe default\n    else:\n        raise","preventionTips":["Treat force_direct_patching and force_sidecar_patching as mutually exclusive in your config layer.","Let the patcher auto-select (pass neither flag) unless you have a specific reason.","For quantized (fp8/bnb) models, never force direct patching."],"tags":["loras","patching","config-conflict"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}