keras-team/keras · error · ValueError

Inputs to `cdist` must have rank >= 2. Received shapes: x.sh

Error message

Inputs to `cdist` must have rank >= 2. Received shapes: x.shape={x.shape}, y.shape={y.shape}

What it means

keras.ops.cdist computes pairwise distances and requires both inputs to be at least rank 2 (a matrix of points, or a batch of such matrices). Cdist.compute_output_spec raises this ValueError when either x.ndim < 2 or y.ndim < 2.

Source

Thrown at keras/src/ops/math.py:380

    3.407606
    """
    if any_symbolic_tensors((x,)):
        return Logsumexp(axis, keepdims).symbolic_call(x)
    return backend.math.logsumexp(x, axis=axis, keepdims=keepdims)


class CDist(Operation):
    def call(self, x, y):
        diff = backend.numpy.expand_dims(x, -2) - backend.numpy.expand_dims(
            y, -3
        )
        return backend.numpy.sqrt(
            backend.numpy.sum(backend.numpy.square(diff), axis=-1)
        )

    def compute_output_spec(self, x, y):
        if x.ndim < 2 or y.ndim < 2:
            raise ValueError(
                "Inputs to `cdist` must have rank >= 2. "
                f"Received shapes: x.shape={x.shape}, y.shape={y.shape}"
            )

        if (
            x.shape[-1] is not None
            and y.shape[-1] is not None
            and x.shape[-1] != y.shape[-1]
        ):
            raise ValueError(
                "The last dimension of inputs to `cdist` must match. "
                f"Received shapes: x.shape={x.shape}, y.shape={y.shape}"
            )

        try:
            batch_shape = broadcast_shapes(x.shape[:-2], y.shape[:-2])
        except ValueError:
            raise ValueError(

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Reshape single points to (1, d): keras.ops.cdist(ops.reshape(p, (1, -1)), points).
  2. Ensure both operands are matrices of shape (..., n, d) and (..., m, d).
  3. Avoid ops.squeeze on the point axis upstream; squeeze only batch axes.

Example fix

// before
from keras import ops
import numpy as np
p = np.array([0.0, 0.0])      # shape (2,)
pts = np.random.rand(5, 2)
d = ops.cdist(p, pts)          # ValueError: p.ndim == 1

// after
p = np.array([0.0, 0.0])
pts = np.random.rand(5, 2)
d = ops.cdist(ops.reshape(p, (1, -1)), pts)  # shape (1, 5)
Defensive patterns

Strategy: validation

Validate before calling

from keras import ops

def as_point_matrix(x):
    if ops.ndim(x) < 2:
        x = ops.expand_dims(x, -2)  # (d,) -> (1, d)
    return x

d = ops.cdist(as_point_matrix(x), as_point_matrix(y))

Type guard

import keras

def cdist_rank_ok(x, y) -> bool:
    return keras.ops.ndim(x) >= 2 and keras.ops.ndim(y) >= 2

Prevention

When it happens

Trigger: Calling keras.ops.cdist(x, y) with 1-D coordinate vectors, e.g. shapes (3,) and (5,); passing a single point without a leading point axis; using cdist inside a model where an upstream squeeze or full reduction removed the point dimension.

Common situations: Migrating from scipy.spatial.distance.cdist and passing 1-D data by mistake; computing distances from one point to a set by passing the point as (d,) instead of (1, d); squeezing batch dims before cdist in a custom loss.

Related errors


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