keras-team/keras · error · ValueError
`mask` should be a list. Received mask=
Error message
`mask` should be a list. Received mask={mask} What it means
Raised by the `Concatenate` layer when the `mask` argument is not a list. When masking is used with `Concatenate`, masks must be provided as a list with one mask per input tensor. Wrap the mask(s) in a list before passing them to the layer.
Solutions
- Pass mask as a list, one per input: Concatenate()([x1, x2], mask=[m1, m2])
- Use None entries for unmasked inputs
- Let Keras propagate masks automatically instead of hand-passing them
Example fix
# before out = layers.Concatenate()([x1, x2], mask=m) # after out = layers.Concatenate()([x1, x2], mask=[m, None])
Defensive patterns
Strategy: validation
Validate before calling
assert mask is None or isinstance(mask, (list, tuple)), 'mask must be a list parallel to inputs'
Type guard
def is_mask_list(mask) -> bool:
return mask is None or isinstance(mask, (list, tuple)) Prevention
- Pass per-input mask lists with None placeholders
- Prefer automatic mask propagation
When it happens
Trigger: Concatenate()([x1, x2], mask=mask_tensor); custom layers passing a bare mask when delegating to a Concatenate layer.
Common situations: Sequence models with mask_zero embeddings feeding a concat; manually constructing mask arguments in custom training loops.
Related errors
- `inputs` should be a list. Received: inputs=
- The lists `inputs` and `mask` should have the same length…
- A `Concatenate` layer requires inputs with matching shapes…
- A `Concatenate` layer should be called on a list of at…
- A `Concatenate` layer should be called on a list of inputs…
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/3d35a3d0b2afdd9b.
Report an issue: GitHub.
Appendix: source
Thrown at keras/src/layers/merging/concatenate.py:126
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}")
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:View on GitHub (pinned to 7a34a03db6)