{"record":{"id":"b4404f88e7058da2","repo":"keras-team/keras","slug":"timedistributed-layer-should-be-passed-an-input","errorCode":null,"errorMessage":"`TimeDistributed` Layer should be passed an `input_shape` with at least 3 dimensions, received: {input_shape}","messagePattern":"`TimeDistributed` Layer should be passed an `input_shape` with at least 3 dimensions, received: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/rnn/time_distributed.py","lineNumber":58,"sourceCode":"            training mode or in inference mode. This argument is passed to the\n            wrapped layer (only if the layer supports this argument).\n        mask: Binary tensor of shape `(samples, timesteps)` indicating whether\n            a given timestep should be masked. This argument is passed to the\n            wrapped layer (only if the layer supports this argument).\n    \"\"\"\n\n    def __init__(self, layer, **kwargs):\n        if not isinstance(layer, Layer):\n            raise ValueError(\n                \"Please initialize `TimeDistributed` layer with a \"\n                f\"`keras.layers.Layer` instance. Received: {layer}\"\n            )\n        super().__init__(layer, **kwargs)\n        self.supports_masking = False\n\n    def _get_child_input_shape(self, input_shape):\n        if not isinstance(input_shape, (tuple, list)) or len(input_shape) < 3:\n            raise ValueError(\n                \"`TimeDistributed` Layer should be passed an `input_shape` \"\n                f\"with at least 3 dimensions, received: {input_shape}\"\n            )\n        return (input_shape[0], *input_shape[2:])\n\n    def compute_output_shape(self, input_shape):\n        child_input_shape = self._get_child_input_shape(input_shape)\n        child_output_shape = self.layer.compute_output_shape(child_input_shape)\n        return (child_output_shape[0], input_shape[1], *child_output_shape[1:])\n\n    def build(self, input_shape):\n        child_input_shape = self._get_child_input_shape(input_shape)\n        super().build(child_input_shape)\n\n    def call(self, inputs, training=None, mask=None):\n        # Validate mask shape using static shape info when available\n        if mask is not None:\n            mask_shape = mask.shape","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/rnn/time_distributed.py#L40-L76","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reshape inputs to 3D+: x = np.expand_dims(x, axis=1) or keras.ops.reshape to (batch, timesteps, features)","If data is not sequential, use a plain Dense/Conv layer instead of TimeDistributed","Check the upstream layer's output shape in model.summary() and insert a Reshape layer if needed"],"exampleFix":"# before\nmodel.add(keras.layers.TimeDistributed(keras.layers.Dense(10), input_shape=(128,)))\n\n# after\nmodel.add(keras.layers.TimeDistributed(keras.layers.Dense(10), input_shape=(1, 128)))","handlingStrategy":"validation","validationCode":"shape = tuple(x.shape)\nif len(shape) < 3:\n    x = keras.ops.expand_dims(x, 1)  # (batch, features) -> (batch, 1, features)\nout = td_layer(x)","typeGuard":"def is_3d_plus(x) -> bool:\n    return len(x.shape) >= 3","tryCatchPattern":null,"preventionTips":["Check x.ndim >= 3 before TimeDistributed; expand dims for single-timestep data","Inspect model.summary() to confirm (batch, timesteps, features) upstream"],"tags":["keras","time-distributed","shape-validation","input-dimensions"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}