keras-team/keras · error · ValueError

A merge layer should be called on a list of inputs. Received

Error message

A merge layer should be called on a list of inputs. Received: inputs={inputs} (not a list of tensors)

What it means

The runtime counterpart of the build-time list check: Merge.call() requires its inputs argument to be a list or tuple of tensors. Passing a single tensor, a dict, or any non-sequence raises immediately.

Source

Thrown at keras/src/layers/merging/base_merge.py:145

        for i in range(1, len(input_shape)):
            if input_shape[i] is None:
                shape = None
            else:
                shape = input_shape[i][1:]
            output_shape = self._compute_elemwise_op_output_shape(
                output_shape, shape
            )

        # If the inputs have different ranks, we have to reshape them
        # to make them broadcastable.
        if None not in input_shape and len(set(map(len, input_shape))) == 1:
            self._reshape_required = False
        else:
            self._reshape_required = True

    def call(self, inputs):
        if not isinstance(inputs, (list, tuple)):
            raise ValueError(
                "A merge layer should be called on a list of inputs. "
                f"Received: inputs={inputs} (not a list of tensors)"
            )
        if self._reshape_required:
            reshaped_inputs = []
            input_ndims = list(map(ops.ndim, inputs))
            if None not in input_ndims:
                # If ranks of all inputs are available,
                # we simply expand each of them at axis=1
                # until all of them have the same rank.
                max_ndim = max(input_ndims)
                for x in inputs:
                    x_ndim = ops.ndim(x)
                    for _ in range(max_ndim - x_ndim):
                        x = ops.expand_dims(x, axis=1)
                    reshaped_inputs.append(x)
                return self._merge_function(reshaped_inputs)
            else:

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Always call merge layers with a list: merge([x, y])
  2. When writing custom call() that delegates to a merge, forward the list structure intact
  3. Fix model serialization/wrappers so the merge layer receives a list at inference

Example fix

# before
out = merge_layer(x)

# after
out = merge_layer([x, x2])
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(inputs, (list, tuple)), 'merge layer needs a list of tensors'

Type guard

def is_tensor_list(x) -> bool:
    return isinstance(x, (list, tuple)) and all(hasattr(t, 'shape') for t in x)

Prevention

When it happens

Trigger: Calling merge_layer(x) with a bare tensor; a saved model that wraps a merge layer where the input list was unwrapped during serialization; custom layers forwarding a single value into a merge call().

Common situations: Refactoring a multi-input model to single input but leaving merge layers in place; deserialization edge cases where lists become single tensors; incorrect use of * unpacking.

Related errors


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