keras-team/keras · error · ValueError

Cannot perform batch_dot over axis 0. If your inputs are not

Error message

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)

What it means

Keras' deprecated symbolic backend batch_dot() refuses to reduce over axis 0 because axis 0 is reserved as the batch dimension. After normalizing negative axes, if either requested axis resolves to 0 the operation is rejected. The error tells you the inputs are probably unbatched single samples.

Source

Thrown at keras/src/legacy/backend.py:113

    if py_any(isinstance(a, (list, tuple)) for a in axes):
        raise ValueError(
            "Multiple target dimensions are not supported. "
            "Expected: None, int, (int, int), "
            f"Provided: {axes}"
        )

    # if tuple, convert to list.
    axes = list(axes)

    # convert negative indices.
    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.

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Add a dummy batch dimension: x = keras.ops.expand_dims(x, 0) (or K.expand_dims(x, 0)) before calling batch_dot, then squeeze it from the result
  2. Choose axes >= 1 that reference real feature dimensions instead of the batch axis
  3. Migrate off keras._legacy.backend.batch_dot to keras.ops.matmul / keras.ops.einsum, which handle unbatched inputs explicitly

Example fix

// before
K.batch_dot(vec_a, vec_b, axes=0)  # ValueError: axis 0 is batch

// after
import keras
a = keras.ops.expand_dims(vec_a, 0)
b = keras.ops.expand_dims(vec_b, 0)
out = keras.ops.squeeze(keras.ops.matmul(a, b, transpose_b=True), 0)
Defensive patterns

Strategy: validation

Validate before calling

def safe_batch_dot_args(x, y, axes):
    axes = list(axes)
    if axes[0] < 0: axes[0] += len(x.shape)
    if axes[1] < 0: axes[1] += len(y.shape)
    assert 0 not in axes, 'axis 0 is the batch axis; expand dims or pick axes >= 1'

Type guard

def is_batched(t) -> bool:
    return t.ndim >= 2  # batch_dot needs a batch dim plus >=1 feature dim

Try / catch

except ValueError as e:
    if 'axis 0' in str(e):
        x = keras.ops.expand_dims(x, 0); y = keras.ops.expand_dims(y, 0)
        out = K.batch_dot(x, y, axes=axes)
    else:
        raise

Prevention

When it happens

Trigger: Calling keras._legacy.backend.batch_dot(x, y, axes=...) (or a legacy layer that routes to it) where the resolved axis for x or y is 0 — e.g. passing 2D tensors shaped (n, m) with axes=0, or a negative axis that normalizes to 0 for low-rank inputs.

Common situations: Porting Keras 1.x/2.x code that called dot()/batch_dot() on single (unbatched) vectors; feeding rank-1 or rank-2 tensors from numpy instead of batched rank-2+ tensors; custom attention layers migrated to the legacy backend namespace.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/0be920850f4eca86. Report an issue: GitHub.