keras-team/keras · critical · ValueError
Layer '{self.name}' was never built and thus it doesn't have
Error message
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.
In most cases, this error indicates that either:
1. 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.
2. 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. What it means
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.
Source
Thrown at keras/src/layers/convolutional/base_conv.py:395
"activity_regularizer": regularizers.serialize(
self.activity_regularizer
),
"kernel_constraint": constraints.serialize(
self.kernel_constraint
),
"bias_constraint": constraints.serialize(self.bias_constraint),
}
)
if self.lora_rank:
config["lora_rank"] = self.lora_rank
config["lora_alpha"] = self.lora_alpha
return config
def _check_load_own_variables(self, store):
all_vars = self._trainable_variables + self._non_trainable_variables
if len(store.keys()) != len(all_vars):
if len(all_vars) == 0 and not self.built:
raise ValueError(
f"Layer '{self.name}' was never built "
"and thus it doesn't have any variables. "
f"However the weights file lists {len(store.keys())} "
"variables for this layer.\n"
"In most cases, this error indicates that either:\n\n"
"1. 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 "
f"the child layer '{self.name}'. A `build()` method "
"must create ALL state for the layer, including "
"the state of any children layers.\n\n"
"2. You need to implement "
"the `def build_from_config(self, config)` method "
f"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)`. "View on GitHub (pinned to 7a34a03db6)
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.
Example fix
# before
class Block(layers.Layer):
def build(self, input_shape):
self.kernel = self.add_weight(shape=input_shape[-1:], name='kernel') # child never built
# after
class Block(layers.Layer):
def build(self, input_shape):
self.conv.build(input_shape) # builds child Conv state
def get_build_config(self):
return {'input_shape': self._build_shape}
def build_from_config(self, config):
self.build(config['input_shape']) Defensive patterns
Strategy: validation
Validate before calling
# CI round-trip test m2 = keras.models.load_model(path) assert [w.shape for w in m.weights] == [w.shape for w in m2.weights]
Type guard
def is_rebuildable(layer) -> bool:
return layer.built or hasattr(layer, 'build_from_config') or layer.count_params() == 0 Try / catch
try:
model = keras.models.load_model(path)
except ValueError as e:
if 'was never built' in str(e):
# fix parent build()/build_from_config, then retry
raise Prevention
- 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
When it happens
Trigger: 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().
Common situations: 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.
Related errors
- Unable to serialize {obj} to JSON. Unrecognized type {type(o
- Method `compute_output_shape()` of layer {self.__class__.__n
- Layer '{self.name}' was never built and thus it doesn't have
- In layer '{self.__class__.__name__}', you forgot to call `su
- Data not JSON Serializable: {data}
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/0d8c266ece30c29d.
Report an issue: GitHub.