{"record":{"id":"0d8c266ece30c29d","repo":"keras-team/keras","slug":"layer-self-name-was-never-built-and-thus-it-do","errorCode":null,"errorMessage":"Layer '{self.name}' was never built and thus it doesn't have any variables. However the weights file lists {len(store.keys())} variables for this layer.\nIn most cases, this error indicates that either:\n\n1. The layer is owned by a parent layer that implements a `build()` method, but calling the parent's `build()` method did NOT create the state of the child layer '{self.name}'. A `build()` method must create ALL state for the layer, including the state of any children layers.\n\n2. You need to implement the `def build_from_config(self, config)` method on layer '{self.name}', to specify how to rebuild it during loading. In this case, you might also want to implement the method that generates the build config at saving time, `def get_build_config(self)`. The method `build_from_config()` is meant to create the state of the layer (i.e. its variables) upon deserialization.","messagePattern":"Layer '\\{self\\.name\\}' was never built and thus it doesn't have any variables\\. However the weights file lists \\{len\\(store\\.keys\\(\\)\\)\\} variables for this layer\\.\nIn most cases, this error indicates that either:\n\n1\\. The layer is owned by a parent layer that implements a `build\\(\\)` method, but calling the parent's `build\\(\\)` method did NOT create the state of the child layer '\\{self\\.name\\}'\\. A `build\\(\\)` method must create ALL state for the layer, including the state of any children layers\\.\n\n2\\. You need to implement the `def build_from_config\\(self, config\\)` method on layer '\\{self\\.name\\}', to specify how to rebuild it during loading\\. In this case, you might also want to implement the method that generates the build config at saving time, `def get_build_config\\(self\\)`\\. The method `build_from_config\\(\\)` is meant to create the state of the layer \\(i\\.e\\. its variables\\) upon deserialization\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"keras/src/layers/convolutional/base_conv.py","lineNumber":395,"sourceCode":"                \"activity_regularizer\": regularizers.serialize(\n                    self.activity_regularizer\n                ),\n                \"kernel_constraint\": constraints.serialize(\n                    self.kernel_constraint\n                ),\n                \"bias_constraint\": constraints.serialize(self.bias_constraint),\n            }\n        )\n        if self.lora_rank:\n            config[\"lora_rank\"] = self.lora_rank\n            config[\"lora_alpha\"] = self.lora_alpha\n        return config\n\n    def _check_load_own_variables(self, store):\n        all_vars = self._trainable_variables + self._non_trainable_variables\n        if len(store.keys()) != len(all_vars):\n            if len(all_vars) == 0 and not self.built:\n                raise ValueError(\n                    f\"Layer '{self.name}' was never built \"\n                    \"and thus it doesn't have any variables. \"\n                    f\"However the weights file lists {len(store.keys())} \"\n                    \"variables for this layer.\\n\"\n                    \"In most cases, this error indicates that either:\\n\\n\"\n                    \"1. The layer is owned by a parent layer that \"\n                    \"implements a `build()` method, but calling the \"\n                    \"parent's `build()` method did NOT create the state of \"\n                    f\"the child layer '{self.name}'. A `build()` method \"\n                    \"must create ALL state for the layer, including \"\n                    \"the state of any children layers.\\n\\n\"\n                    \"2. You need to implement \"\n                    \"the `def build_from_config(self, config)` method \"\n                    f\"on layer '{self.name}', to specify how to rebuild \"\n                    \"it during loading. \"\n                    \"In this case, you might also want to implement the \"\n                    \"method that generates the build config at saving time, \"\n                    \"`def get_build_config(self)`. \"","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/convolutional/base_conv.py#L377-L413","documentation":"Raised when loading weights into a Keras layer whose variable count doesn't match the weights file: the layer has zero variables because it was never built, yet the checkpoint lists variables for it. Keras builds layer state lazily in build(), so a layer with no variables at load time means its state was never created during deserialization. The message points at two root causes: a parent layer's build() that fails to create child state, or missing build_from_config()/get_build_config() support for rebuilding during loading.","triggerScenarios":"Calling keras.models.load_model() (or layer.load_own_variables(store)) on a model containing a custom layer (e.g. a Conv subclass) owned by a parent layer whose build() does not build the child; or loading a model saved with a build config when the custom layer does not implement build_from_config(self, config) and get_build_config().","commonSituations":"Custom multi-layer wrappers (e.g. ConvBlock owning Conv2D+BN) where the parent's build creates weights directly instead of building children; loading models across Keras 2->3 migration; custom layers restored from config whose build never runs because build_from_config is absent.","solutions":["In the parent layer's build(), explicitly create child state, e.g. self.conv.build(input_shape).","Implement get_build_config(self) and build_from_config(self, config) so the layer rebuilds its state on load.","Add a save/load round-trip test comparing layer weights before and after.","If the layer legitimately has no weights, fix the checkpoint or exclude it from saved variables."],"exampleFix":"# before\nclass Block(layers.Layer):\n    def build(self, input_shape):\n        self.kernel = self.add_weight(shape=input_shape[-1:], name='kernel')  # child never built\n\n# after\nclass Block(layers.Layer):\n    def build(self, input_shape):\n        self.conv.build(input_shape)  # builds child Conv state\n    def get_build_config(self):\n        return {'input_shape': self._build_shape}\n    def build_from_config(self, config):\n        self.build(config['input_shape'])","handlingStrategy":"validation","validationCode":"# CI round-trip test\nm2 = keras.models.load_model(path)\nassert [w.shape for w in m.weights] == [w.shape for w in m2.weights]","typeGuard":"def is_rebuildable(layer) -> bool:\n    return layer.built or hasattr(layer, 'build_from_config') or layer.count_params() == 0","tryCatchPattern":"try:\n    model = keras.models.load_model(path)\nexcept ValueError as e:\n    if 'was never built' in str(e):\n        # fix parent build()/build_from_config, then retry\n        raise","preventionTips":["Implement get_build_config/build_from_config on custom layers with children","Make parent build() explicitly build child layers","Add a save/load round-trip test to CI"],"tags":["keras","model-loading","custom-layers","serialization"],"backgroundTag":"keras-layer-never-built-on-load","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}