keras-team/keras · error · ValueError

Cannot do batch_dot on inputs with rank < 2. Received inputs

Error message

Cannot do batch_dot on inputs with rank < 2. Received inputs with tf.shapes {x_shape} and {y_shape}.

What it means

The legacy keras backend batch_dot operation performs a batched dot product, which needs a batch axis plus at least one feature axis per operand — rank >= 2 for both x and y. Inputs of rank 0 or 1 (scalars or vectors) have no batch dimension to align, so the function raises before computing anything.

Source

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

    if stop is None and start < 0:
        start = 0
    result = tf.range(start, limit=stop, delta=step, name="arange")
    if dtype != "int32":
        result = tf.cast(result, dtype)
    return result


@keras_export("keras._legacy.backend.batch_dot")
def batch_dot(x, y, axes=None):
    """DEPRECATED."""
    x_shape = x.shape
    y_shape = y.shape

    x_ndim = len(x_shape)
    y_ndim = len(y_shape)

    if x_ndim < 2 or y_ndim < 2:
        raise ValueError(
            "Cannot do batch_dot on inputs "
            "with rank < 2. "
            f"Received inputs with tf.shapes {x_shape} and {y_shape}."
        )

    x_batch_size = x_shape[0]
    y_batch_size = y_shape[0]

    if x_batch_size is not None and y_batch_size is not None:
        if x_batch_size != y_batch_size:
            raise ValueError(
                "Cannot do batch_dot on inputs "
                "with different batch sizes. "
                "Received inputs with tf.shapes "
                f"{x_shape} and {y_shape}."
            )
    if isinstance(axes, int):
        axes = [axes, axes]

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Expand dims to restore the batch axis: x = keras.ops.expand_dims(x, 0) (or axis=-1 for a feature axis) so both operands are >= 2D
  2. For plain vector/matrix products without a batch axis, use keras.ops.dot or matmul instead
  3. Audit squeeze() calls whose results feed into batch_dot

Example fix

# before
score = keras.ops.batch_dot(vec_a, vec_b)  # both shape (128,)

# after
score = keras.ops.batch_dot(keras.ops.expand_dims(vec_a, 0), keras.ops.expand_dims(vec_b, 0))
Defensive patterns

Strategy: validation

Validate before calling

if len(x.shape) < 2:
    x = keras.ops.expand_dims(x, 0)
if len(y.shape) < 2:
    y = keras.ops.expand_dims(y, 0)
out = keras.ops.batch_dot(x, y)

Type guard

def is_rank2_plus(t) -> bool:
    return len(t.shape) >= 2

Prevention

When it happens

Trigger: Calling batch_dot with a 1D vector (shape (n,)) or scalar on either side; forgetting to expand dims on per-sample vectors before dotting; passing the output of a squeeze that removed the batch axis.

Common situations: Computing per-sample cosine similarity on 1D embeddings without expanding dims; using old keras.backend.batch_dot code from Keras 2 in Keras 3; squeezing tensors for logging then reusing them in a loss.

Related errors


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