keras-team/keras · error · ValueError
Cannot do batch_dot on inputs with tf.shapes {x_shape} and {
Error message
Cannot do batch_dot on inputs with tf.shapes {x_shape} and {y_shape} with axes={axes}. x.shape[%d] != y.shape[%d] (%d != %d). What it means
batch_dot() requires the dimension of x selected by axes[0] to equal the dimension of y selected by axes[1]; a batched dot product is only defined for matching contraction sizes. When both static shapes are known and disagree, Keras raises this before touching the graph. The message prints both shapes and the axes so the mismatch can be located by inspection.
Source
Thrown at keras/src/legacy/backend.py:124
if axes[0] < 0:
axes[0] += x_ndim
if axes[1] < 0:
axes[1] += y_ndim
# sanity checks
if 0 in axes:
raise ValueError(
"Cannot perform batch_dot over axis 0. "
"If your inputs are not batched, "
"add a dummy batch dimension to your "
"inputs using K.expand_dims(x, 0)"
)
a0, a1 = axes
d1 = x_shape[a0]
d2 = y_shape[a1]
if d1 is not None and d2 is not None and d1 != d2:
raise ValueError(
"Cannot do batch_dot on inputs with tf.shapes "
f"{x_shape} and {y_shape} with axes={axes}. "
"x.shape[%d] != y.shape[%d] (%d != %d)."
% (axes[0], axes[1], d1, d2)
)
# backup ndims. Need them later.
orig_x_ndim = x_ndim
orig_y_ndim = y_ndim
# if rank is 2, expand to 3.
if x_ndim == 2:
x = tf.expand_dims(x, 1)
a0 += 1
x_ndim += 1
if y_ndim == 2:
y = tf.expand_dims(y, 2)
y_ndim += 1View on GitHub (pinned to 7a34a03db6)
Solutions
- Make the contracted dimensions equal: adjust the preceding Dense/kernel so x.shape[axes[0]] == y.shape[axes[1]]
- Re-check the axes argument — often you want axes=(2,1) or a transpose on one operand rather than the default
- Add/verify a projection layer (Dense to the common size) on the mismatched operand
Example fix
// before out = K.batch_dot(q, k) # q:(8,16), k:(8,32) -> ValueError // after k_proj = keras.layers.Dense(16)(k) out = K.batch_dot(q, k_proj)
Defensive patterns
Strategy: validation
Validate before calling
assert x.shape[axes[0]] is None or y.shape[axes[1]] is None or x.shape[axes[0]] == y.shape[axes[1]], f'{x.shape} vs {y.shape} on axes {axes}' Type guard
def compatible_batch_dot(x, y, axes=(1, 1)) -> bool:
d1, d2 = x.shape[axes[0]], y.shape[axes[1]]
return d1 is None or d2 is None or d1 == d2 Try / catch
except ValueError as e:
if 'x.shape' in str(e):
raise ValueError(f'contraction dims mismatch — project one side: {e}') from e
raise Prevention
- Print/assert static shapes before batch_dot in layer tests
- Keep query/key projection sizes equal in attention layers
- Document which axes each operand is contracted on
When it happens
Trigger: batch_dot(x, y, axes=(i, j)) where x.shape[i] != y.shape[j], e.g. x shape (8, 16) dotted with y shape (8, 32) on default axes (1, 1) — contracting 16 against 32.
Common situations: Attention layers where query/key feature sizes differ (e.g. after a projection); hand-written merge layers ported from old Keras; transposition mistakes where one operand needs transpose_b or axes=(2,1).
Related errors
- Cannot perform batch_dot over axis 0. If your inputs are not
- The TFSMLayer is only currently supported with the TensorFlo
- Cannot do batch_dot on inputs with rank < 2. Received inputs
- Layer HashedCrossing requires TensorFlow. Install it via `pi
- Layer Hashing requires TensorFlow. Install it via `pip insta
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/f85c35b3c9245eed.
Report an issue: GitHub.