keras-team/keras · error · ValueError

A `Concatenate` layer should be called on a list of inputs.

Error message

A `Concatenate` layer should be called on a list of inputs. Received: input_shape={input_shape}

What it means

Concatenate.compute_output_shape requires input_shape to be a list of shapes (input_shape[0] itself a tuple/list). If called with a single tensor's shape, the shape math for concatenation cannot proceed and this ValueError is raised.

Source

Thrown at keras/src/layers/merging/concatenate.py:108

            for axis in range(rank):
                # Skip the Nones in the shape since they are dynamic, also the
                # axis for concat has been removed above.
                unique_dims = set(
                    shape[axis]
                    for shape in shape_set
                    if shape[axis] is not None
                )
                if len(unique_dims) > 1:
                    raise ValueError(err_msg)

    def _merge_function(self, inputs):
        return ops.concatenate(inputs, axis=self.axis)

    def compute_output_shape(self, input_shape):
        if (not isinstance(input_shape, (tuple, list))) or (
            not isinstance(input_shape[0], (tuple, list))
        ):
            raise ValueError(
                "A `Concatenate` layer should be called on a list of inputs. "
                f"Received: input_shape={input_shape}"
            )
        input_shapes = input_shape
        output_shape = list(input_shapes[0])

        for shape in input_shapes[1:]:
            if output_shape[self.axis] is None or shape[self.axis] is None:
                output_shape[self.axis] = None
                break
            output_shape[self.axis] += shape[self.axis]
        return tuple(output_shape)

    def compute_mask(self, inputs, mask=None):
        if mask is None:
            return None
        if not isinstance(mask, (tuple, list)):
            raise ValueError(f"`mask` should be a list. Received mask={mask}")

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass a list of shapes: layer.compute_output_shape([s1, s2])
  2. In Functional graphs, ensure the concat node receives a list of input tensors
  3. Fix custom layers that forward single shapes into Concatenate.compute_output_shape

Example fix

# before
shape = concat.compute_output_shape((None, 10))

# after
shape = concat.compute_output_shape([(None, 10), (None, 20)])
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(input_shape, (list, tuple)) and isinstance(input_shape[0], (list, tuple))

Type guard

def is_shape_list(input_shape) -> bool:
    return isinstance(input_shape, (list, tuple)) and len(input_shape) > 0 and isinstance(input_shape[0], (list, tuple))

Prevention

When it happens

Trigger: Calling compute_output_shape((None, 10)) directly; Functional model graph construction where the concat layer is wired to a single input; subclass overriding and forwarding a bare shape.

Common situations: Programmatic shape inference on models; incorrect list nesting when building functional models; debugging utilities calling compute_output_shape with unwrapped shapes.

Related errors


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