keras-team/keras · error · ValueError

Please initialize `TimeDistributed` layer with a `keras.laye

Error message

Please initialize `TimeDistributed` layer with a `keras.layers.Layer` instance. Received: {layer}

What it means

TimeDistributed wraps a single Keras Layer and applies it independently at every timestep. Its constructor enforces `isinstance(layer, Layer)` so that it can delegate build/call and output-shape computation; anything else (a string name, a function, a model config) is rejected immediately.

Source

Thrown at keras/src/layers/rnn/time_distributed.py:49

    the timestamps, the same set of weights are used at each timestamp.

    Args:
        layer: a `keras.layers.Layer` instance.

    Call arguments:
        inputs: Input tensor of shape (batch, time, ...) or nested tensors,
            and each of which has shape (batch, time, ...).
        training: Python boolean indicating whether the layer should behave in
            training mode or in inference mode. This argument is passed to the
            wrapped layer (only if the layer supports this argument).
        mask: Binary tensor of shape `(samples, timesteps)` indicating whether
            a given timestep should be masked. This argument is passed to the
            wrapped layer (only if the layer supports this argument).
    """

    def __init__(self, layer, **kwargs):
        if not isinstance(layer, Layer):
            raise ValueError(
                "Please initialize `TimeDistributed` layer with a "
                f"`keras.layers.Layer` instance. Received: {layer}"
            )
        super().__init__(layer, **kwargs)
        self.supports_masking = False

    def _get_child_input_shape(self, input_shape):
        if not isinstance(input_shape, (tuple, list)) or len(input_shape) < 3:
            raise ValueError(
                "`TimeDistributed` Layer should be passed an `input_shape` "
                f"with at least 3 dimensions, received: {input_shape}"
            )
        return (input_shape[0], *input_shape[2:])

    def compute_output_shape(self, input_shape):
        child_input_shape = self._get_child_input_shape(input_shape)
        child_output_shape = self.layer.compute_output_shape(child_input_shape)
        return (child_output_shape[0], input_shape[1], *child_output_shape[1:])

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass an instantiated layer: TimeDistributed(keras.layers.Dense(10))
  2. Wrap raw functions in a Lambda layer first: TimeDistributed(keras.layers.Lambda(fn))
  3. When loading from config, deserialize to a Layer object before wrapping

Example fix

# before
layer = keras.layers.TimeDistributed('Dense')

# after
layer = keras.layers.TimeDistributed(keras.layers.Dense(10))
Defensive patterns

Strategy: type-guard

Validate before calling

from keras.layers import Layer
assert isinstance(inner, Layer), f'TimeDistributed needs a Layer, got {type(inner)}'
td = keras.layers.TimeDistributed(inner)

Type guard

from keras.layers import Layer

def is_keras_layer(obj) -> bool:
    return isinstance(obj, Layer)

Prevention

When it happens

Trigger: Calling keras.layers.TimeDistributed('Dense') or TimeDistributed(some_python_function) or passing a dict config instead of a layer instance; also nesting wrappers incorrectly such as TimeDistributed(TimeDistributed(dense)) where an unexpected object slips through.

Common situations: Porting old Keras 1.x code where layers could be referenced by name; passing a lambda or a backend function instead of a keras.layers wrapper; JSON-deserializing a model config without using keras.layers.deserialize first.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/941acfab2a41ebf3. Report an issue: GitHub.