{"record":{"id":"3d35a3d0b2afdd9b","repo":"keras-team/keras","slug":"mask-should-be-a-list-received-mask-mask-3d35a3","errorCode":null,"errorMessage":"`mask` should be a list. Received mask={mask}","messagePattern":"`mask` should be a list\\. Received mask=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/merging/concatenate.py","lineNumber":126,"sourceCode":"            raise ValueError(\n                \"A `Concatenate` layer should be called on a list of inputs. \"\n                f\"Received: input_shape={input_shape}\"\n            )\n        input_shapes = input_shape\n        output_shape = list(input_shapes[0])\n\n        for shape in input_shapes[1:]:\n            if output_shape[self.axis] is None or shape[self.axis] is None:\n                output_shape[self.axis] = None\n                break\n            output_shape[self.axis] += shape[self.axis]\n        return tuple(output_shape)\n\n    def compute_mask(self, inputs, mask=None):\n        if mask is None:\n            return None\n        if not isinstance(mask, (tuple, list)):\n            raise ValueError(f\"`mask` should be a list. Received mask={mask}\")\n        if not isinstance(inputs, (tuple, list)):\n            raise ValueError(\n                f\"`inputs` should be a list. Received: inputs={inputs}\"\n            )\n        if len(mask) != len(inputs):\n            raise ValueError(\n                \"The lists `inputs` and `mask` should have the same length. \"\n                f\"Received: inputs={inputs} of length {len(inputs)}, and \"\n                f\"mask={mask} of length {len(mask)}\"\n            )\n        if all(m is None for m in mask):\n            return None\n        # Make a list of masks while making sure\n        # the dimensionality of each mask\n        # is the same as the corresponding input.\n        masks = []\n        for input_i, mask_i in zip(inputs, mask):\n            if mask_i is None:","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/merging/concatenate.py#L108-L144","documentation":"Concatenate.compute_mask requires a provided mask to be a list/tuple parallel to the inputs. Passing a single mask tensor (or any non-sequence) raises this error.","triggerScenarios":"Concatenate()([x1, x2], mask=mask_tensor); custom layers passing a bare mask when delegating to a Concatenate layer.","commonSituations":"Sequence models with mask_zero embeddings feeding a concat; manually constructing mask arguments in custom training loops.","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"],"exampleFix":"# before\nout = layers.Concatenate()([x1, x2], mask=m)\n\n# after\nout = layers.Concatenate()([x1, x2], mask=[m, None])","handlingStrategy":"validation","validationCode":"assert mask is None or isinstance(mask, (list, tuple)), 'mask must be a list parallel to inputs'","typeGuard":"def is_mask_list(mask) -> bool:\n    return mask is None or isinstance(mask, (list, tuple))","tryCatchPattern":null,"preventionTips":["Pass per-input mask lists with None placeholders","Prefer automatic mask propagation"],"tags":["keras","concatenate","masking"],"backgroundTag":"wrong-argument-structure","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}