keras-team/keras · error · ValueError

`TimeDistributed` Layer should be passed an `input_shape` wi

Error message

`TimeDistributed` Layer should be passed an `input_shape` with at least 3 dimensions, received: {input_shape}

What it means

TimeDistributed needs one dimension for the batch, one for timesteps, and at least one feature dimension, so `_get_child_input_shape` requires an input_shape that is a tuple/list of length >= 3 and strips the time axis (returns (input_shape[0], *input_shape[2:])). Shapes with fewer axes (e.g. (batch, features)) cannot be split per timestep, so build/compute_output_shape raises.

Source

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

            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:])

    def build(self, input_shape):
        child_input_shape = self._get_child_input_shape(input_shape)
        super().build(child_input_shape)

    def call(self, inputs, training=None, mask=None):
        # Validate mask shape using static shape info when available
        if mask is not None:
            mask_shape = mask.shape

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Reshape inputs to 3D+: x = np.expand_dims(x, axis=1) or keras.ops.reshape to (batch, timesteps, features)
  2. If data is not sequential, use a plain Dense/Conv layer instead of TimeDistributed
  3. Check the upstream layer's output shape in model.summary() and insert a Reshape layer if needed

Example fix

# before
model.add(keras.layers.TimeDistributed(keras.layers.Dense(10), input_shape=(128,)))

# after
model.add(keras.layers.TimeDistributed(keras.layers.Dense(10), input_shape=(1, 128)))
Defensive patterns

Strategy: validation

Validate before calling

shape = tuple(x.shape)
if len(shape) < 3:
    x = keras.ops.expand_dims(x, 1)  # (batch, features) -> (batch, 1, features)
out = td_layer(x)

Type guard

def is_3d_plus(x) -> bool:
    return len(x.shape) >= 3

Prevention

When it happens

Trigger: Feeding TimeDistributed a 2D input like (batch_size, features), a 1D tensor, or a non tuple/list shape; also calling build((None, 10)) or compute_output_shape on such a shape directly.

Common situations: Forgetting to expand dims for a sequence: passing (batch, features) instead of (batch, timesteps, features); feeding output of a Dense layer straight into TimeDistributed; reshaping mistakes in preprocessing; mixing up TimeDistributed with Dense for non-sequential data.

Related errors


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