{"record":{"id":"a7fae5b272eb6e30","repo":"keras-team/keras","slug":"a-concatenate-layer-requires-inputs-with-matchin","errorCode":null,"errorMessage":"A `Concatenate` layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape={input_shape}","messagePattern":"A `Concatenate` layer requires inputs with matching shapes except for the concatenation axis\\. Received: input_shape=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/merging/concatenate.py","lineNumber":87,"sourceCode":"                # but if tensor shapes are not the same when\n                # calling, an exception will be raised.\n                if axis != concat_axis and axis_value == 1:\n                    del reduced_inputs_shapes[i][axis]\n\n            if len(reduced_inputs_shapes[i]) > self.axis:\n                del reduced_inputs_shapes[i][self.axis]\n            shape_set.add(tuple(reduced_inputs_shapes[i]))\n\n        if len(shape_set) != 1:\n            err_msg = (\n                \"A `Concatenate` layer requires inputs with matching shapes \"\n                \"except for the concatenation axis. \"\n                f\"Received: input_shape={input_shape}\"\n            )\n            # Make sure all the shapes have same ranks.\n            ranks = set(len(shape) for shape in shape_set)\n            if len(ranks) != 1:\n                raise ValueError(err_msg)\n            # Get the only rank for the set.\n            (rank,) = ranks\n            for axis in range(rank):\n                # Skip the Nones in the shape since they are dynamic, also the\n                # axis for concat has been removed above.\n                unique_dims = set(\n                    shape[axis]\n                    for shape in shape_set\n                    if shape[axis] is not None\n                )\n                if len(unique_dims) > 1:\n                    raise ValueError(err_msg)\n\n    def _merge_function(self, inputs):\n        return ops.concatenate(inputs, axis=self.axis)\n\n    def compute_output_shape(self, input_shape):\n        if (not isinstance(input_shape, (tuple, list))) or (","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/merging/concatenate.py#L69-L105","documentation":"During Concatenate.build, all input shapes must have the same rank (number of dimensions) apart from the concat axis. This specific raise fires when the set of ranks has more than one value, e.g. merging a rank-3 feature map with a rank-2 vector.","triggerScenarios":"Concatenate()([conv_out, dense_out]) where conv_out is (None,8,8,64) and dense_out is (None,128); merging an image tensor with a flat metadata vector.","commonSituations":"Fusing CNN features with tabular vectors without reshaping; forgetting Flatten/GlobalAveragePooling before concat; mixing sequence and static features.","solutions":["Insert Flatten, GlobalAveragePooling2D, or Reshape so all inputs share rank","Expand dims of the lower-rank tensor (e.g. ops.expand_dims(v, 1)) to match","Double-check the axis parameter — it must be valid for the common rank"],"exampleFix":"# before\nout = layers.Concatenate()([conv_feat, flat_vec])  # rank 4 vs rank 2\n\n# after\nconv_feat = layers.GlobalAveragePooling2D()(conv_feat)  # rank 2\nout = layers.Concatenate()([conv_feat, flat_vec])","handlingStrategy":"validation","validationCode":"ranks = {len(tuple(t.shape)) for t in inputs}\nassert len(ranks) == 1, f'rank mismatch before concat: {ranks}'","typeGuard":"def same_rank(inputs) -> bool:\n    shapes = [tuple(t.shape) for t in inputs]\n    return len({len(s) for s in shapes}) == 1","tryCatchPattern":null,"preventionTips":["Flatten or pool feature maps before concatenating with vectors","Check ndim before concat in dynamic code"],"tags":["keras","concatenate","rank-mismatch","shape-mismatch"],"backgroundTag":"tensor-rank-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}