{"record":{"id":"91fc800a99ea94f9","repo":"keras-team/keras","slug":"a-merge-layer-should-be-called-on-a-list-of-inputs","errorCode":null,"errorMessage":"A merge layer should be called on a list of inputs. Received: input_shape={input_shape} (not a list of shapes)","messagePattern":"A merge layer should be called on a list of inputs\\. Received: input_shape=(.+?) \\(not a list of shapes\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/merging/base_merge.py","lineNumber":103,"sourceCode":"            if i is None or j is None:\n                output_shape.append(None)\n            elif i == 1:\n                output_shape.append(j)\n            elif j == 1:\n                output_shape.append(i)\n            else:\n                if i != j:\n                    raise ValueError(\n                        \"Inputs have incompatible shapes. \"\n                        f\"Received shapes {shape1} and {shape2}\"\n                    )\n                output_shape.append(i)\n        return tuple(output_shape)\n\n    def build(self, input_shape):\n        # Used purely for shape validation.\n        if not isinstance(input_shape[0], (tuple, list)):\n            raise ValueError(\n                \"A merge layer should be called on a list of inputs. \"\n                f\"Received: input_shape={input_shape} (not a list of shapes)\"\n            )\n        if len(input_shape) < 1:\n            raise ValueError(\n                \"A merge layer should be called \"\n                \"on a list of at least 1 input. \"\n                f\"Received {len(input_shape)} inputs. \"\n                f\"Full input_shape received: {input_shape}\"\n            )\n\n        batch_sizes = {s[0] for s in input_shape if s} - {None}\n        if len(batch_sizes) > 1:\n            raise ValueError(\n                \"Cannot merge tensors with different batch sizes. \"\n                f\"Received tensors with shapes {input_shape}\"\n            )\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/merging/base_merge.py#L85-L121","documentation":"Merge layers expect build(input_shape) to receive a list of shapes, one per input tensor. This check fails when input_shape[0] is not itself a tuple/list — i.e. the layer was effectively called with a single tensor (or something that is not a nest of shapes), so Keras cannot treat the call as a multi-input merge.","triggerScenarios":"Calling Add()(x) with a single tensor instead of a list; passing a dict or scalar where a list of shapes is expected; a custom layer delegating to a merge layer with the wrong input structure.","commonSituations":"Forgetting brackets: Add()(x) instead of Add()([x, y]); a Functional model where a single previous tensor node feeds the merge layer; wrapping merge layers in custom code.","solutions":["Pass a list of at least two tensors: Add()([x, y])","In Functional models, ensure the merge layer receives a list input: layers.Add()([branch_a, branch_b])","Wrap a lone tensor in a list only if you truly mean single-input merge behavior"],"exampleFix":"# before\nout = layers.Add()(x)\n\n# after\nout = layers.Add()([x, y])","handlingStrategy":"type-guard","validationCode":"assert isinstance(inputs, (list, tuple)) and len(inputs) >= 2 and all(hasattr(t, 'shape') for t in inputs)","typeGuard":"def is_merge_input_list(inputs) -> bool:\n    return isinstance(inputs, (list, tuple)) and len(inputs) >= 2","tryCatchPattern":null,"preventionTips":["Always wrap merge inputs in a list literal","Review code paths where a single tensor may reach the merge","Validate list structure in dynamic pipelines"],"tags":["keras","merge","input-format","api-misuse"],"backgroundTag":"wrong-argument-structure","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}