{"record":{"id":"b4f818e71dd8e6b3","repo":"keras-team/keras","slug":"cannot-enable-lora-on-a-layer-that-isn-t-yet-built-b4f818","errorCode":null,"errorMessage":"Cannot enable lora on a layer that isn't yet built.","messagePattern":"Cannot enable lora on a layer that isn't yet built\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/core/einsum_dense.py","lineNumber":341,"sourceCode":"        if self.activation is not None:\n            x = self.activation(x)\n        return x\n\n    def enable_lora(\n        self,\n        rank,\n        lora_alpha=None,\n        a_initializer=\"he_uniform\",\n        b_initializer=\"zeros\",\n    ):\n        if self.kernel_constraint:\n            raise ValueError(\n                \"Lora is incompatible with kernel constraints. \"\n                \"In order to enable lora on this layer, remove the \"\n                \"`kernel_constraint` argument.\"\n            )\n        if not self.built:\n            raise ValueError(\n                \"Cannot enable lora on a layer that isn't yet built.\"\n            )\n        if self.lora_enabled:\n            raise ValueError(\n                \"lora is already enabled. This can only be done once per layer.\"\n            )\n        if self.quantization_mode == \"gptq\":\n            raise NotImplementedError(\n                \"lora is not currently supported with GPTQ quantization.\"\n            )\n        self._tracker.unlock()\n        # Determine the appropriate (unpacked) kernel shape for LoRA.\n        if self.quantization_mode == \"int4\":\n            # INT4 weights are stored in a flattened 2D layout that loses\n            # the original N-dimensional structure required by the einsum\n            # equation. We use `original_kernel_shape`` to ensure LoRA adapters\n            # operate in the correct logical dimension space.\n            kernel_shape_for_lora = tuple(self.original_kernel_shape)","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/core/einsum_dense.py#L323-L359","documentation":"EinsumDense.enable_lora() requires the layer to already be built (its kernel shape known) because the LoRA A/B matrices are created against the actual kernel dimensions. Calling it on an unbuilt layer raises this ValueError immediately so LoRA state is never half-initialized.","triggerScenarios":"layer = keras.layers.EinsumDense(...); layer.enable_lora(4) before any input has triggered build(); enabling LoRA on a freshly constructed model that was never called on data or build()ed explicitly.","commonSituations":"Script order mistakes — enabling LoRA right after model construction instead of after building; functional models where you forgot model.build(input_shape) or a dummy forward pass before PEFT setup; migrating from libraries that implicitly build layers.","solutions":["Call the model on a dummy input once, or layer.build(input_shape), so the layer is built, then enable_lora.","For Functional/Sequential models, run model.build(input_shape) before enabling LoRA.","If loading from a checkpoint, enable LoRA after weights are loaded (loading guarantees build)."],"exampleFix":"# before\nlayer = keras.layers.EinsumDense('ab,bc->ac', output_dim=64)\nlayer.enable_lora(rank=8)  # ValueError: not yet built\n\n# after\nlayer = keras.layers.EinsumDense('ab,bc->ac', output_dim=64)\nlayer.build(input_shape=(None, 128))\nlayer.enable_lora(rank=8)","handlingStrategy":"validation","validationCode":"if not layer.built:\n    layer.build(input_shape)\nlayer.enable_lora(rank)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build the model (dummy forward pass or model.build) before PEFT setup.","Centralize enable_lora calls in one post-build function."],"tags":["keras","lora","einsum-dense","layer-build","peft"],"backgroundTag":"lora-layer-not-built","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}