keras-team/keras · error · ValueError
Cannot merge tensors with different batch sizes. Received te
Error message
Cannot merge tensors with different batch sizes. Received tensors with shapes {input_shape} What it means
Merge layers require all input tensors to share the same batch dimension (None wildcard allowed). build() collects the first element of each input shape and raises if more than one distinct non-None batch size appears, because element-wise merging across different batch sizes is undefined.
Source
Thrown at keras/src/layers/merging/base_merge.py:117
def build(self, input_shape):
# Used purely for shape validation.
if not isinstance(input_shape[0], (tuple, list)):
raise ValueError(
"A merge layer should be called on a list of inputs. "
f"Received: input_shape={input_shape} (not a list of shapes)"
)
if len(input_shape) < 1:
raise ValueError(
"A merge layer should be called "
"on a list of at least 1 input. "
f"Received {len(input_shape)} inputs. "
f"Full input_shape received: {input_shape}"
)
batch_sizes = {s[0] for s in input_shape if s} - {None}
if len(batch_sizes) > 1:
raise ValueError(
"Cannot merge tensors with different batch sizes. "
f"Received tensors with shapes {input_shape}"
)
if input_shape[0] is None:
output_shape = None
else:
output_shape = input_shape[0][1:]
for i in range(1, len(input_shape)):
if input_shape[i] is None:
shape = None
else:
shape = input_shape[i][1:]
output_shape = self._compute_elemwise_op_output_shape(
output_shape, shape
)
View on GitHub (pinned to 7a34a03db6)
Solutions
- Make batch dimensions consistent: use None (dynamic) batch in all Input definitions
- Slice or pad one tensor so both have the same number of samples per batch
- Remove batch_size=... hardcoding on Inputs feeding the merge
Example fix
# before a = keras.Input(shape=(16,), batch_size=32) b = keras.Input(shape=(16,)) # runtime batch 64 out = layers.Add()([a, b]) # ValueError # after a = keras.Input(shape=(16,)) out = layers.Add()([a, b])
Defensive patterns
Strategy: validation
Validate before calling
batch_sizes = {tuple(t.shape)[0] for t in inputs if len(t.shape)} - {None}
assert len(batch_sizes) <= 1, f'conflicting batch sizes: {batch_sizes}' Type guard
def same_batch_size(shapes) -> bool:
bs = {s[0] for s in shapes if s} - {None}
return len(bs) <= 1 Prevention
- Prefer dynamic (None) batch dimensions in Input definitions
- Verify dataset batch sizes across modalities before merging
- Avoid hardcoding batch_size when downstream merges exist
When it happens
Trigger: Calling Add()([x, y]) where x has batch size 32 and y has batch size 64; merging a fixed-batch Input with a dynamic-batch Input is allowed, but 32 vs 64 fails.
Common situations: Hardcoded batch dimensions in Input(shape=..., batch_size=32) mixing with dynamic batches; slicing one branch to a different number of samples; data pipelines producing mismatched batch sizes across modalities.
Related errors
- Inputs have incompatible shapes. Received shapes {shape1} an
- Architecture configuration does not match {weights_name} var
- Model name "{name}" does not match weights variant "{weights
- DenseNet does not support the `channels_first` image data fo
- The last dimension of `query_shape` and `value_shape` must b
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/b9ac6590d51deefd.
Report an issue: GitHub.