keras-team/keras · error · ValueError

The lists `inputs` and `mask` should have the same length. R

Error message

The lists `inputs` and `mask` should have the same length. Received: inputs={inputs} of length {len(inputs)}, and mask={mask} of length {len(mask)}

What it means

Concatenate.compute_mask requires len(mask) == len(inputs) so it can align each mask with its input. This error fires when the mask list length differs from the number of input tensors.

Source

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

        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}")
        if not isinstance(inputs, (tuple, list)):
            raise ValueError(
                f"`inputs` should be a list. Received: inputs={inputs}"
            )
        if len(mask) != len(inputs):
            raise ValueError(
                "The lists `inputs` and `mask` should have the same length. "
                f"Received: inputs={inputs} of length {len(inputs)}, and "
                f"mask={mask} of length {len(mask)}"
            )
        if all(m is None for m in mask):
            return None
        # Make a list of masks while making sure
        # the dimensionality of each mask
        # is the same as the corresponding input.
        masks = []
        for input_i, mask_i in zip(inputs, mask):
            if mask_i is None:
                # Input is unmasked. Append all 1s to masks,
                masks.append(ops.ones_like(input_i, dtype="bool"))
            elif mask_i.ndim < input_i.ndim:
                # Broadcast mask shape to match in a way where we capture the
                # input as a symbolic input in the op graph.
                mask_i = ops.logical_or(

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Provide exactly one mask entry per input, using None where absent: mask=[m1, None, m2]
  2. Regenerate mask lists whenever the input list changes
  3. Prefer automatic mask propagation over manual mask plumbing

Example fix

# before
out = concat([x1, x2, x3], mask=[m1, m2])

# after
out = concat([x1, x2, x3], mask=[m1, None, m2])
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(mask, (list, tuple)) and len(mask) == len(inputs)

Type guard

def masks_match_inputs(mask, inputs) -> bool:
    return mask is None or (isinstance(mask, (list, tuple)) and len(mask) == len(inputs))

Prevention

When it happens

Trigger: Concatenate()([x1, x2, x3], mask=[m1, m2]); omitting None placeholders for unmasked inputs.

Common situations: Adding an input to the concat but not the mask list; mixed masked/unmasked inputs; refactoring input arity.

Related errors


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