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
- Reshape single points to (1, d): keras.ops.cdist(ops.reshape(p, (1, -1)), points).
- Ensure both operands are matrices of shape (..., n, d) and (..., m, d).
- 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
- Never pass bare vectors to cdist; wrap single points as (1, d).
- Avoid full squeezes upstream of distance computation.
- Mirror scipy usage: cdist wants 2-D there too.
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
- The last dimension of inputs to `cdist` must match. Received
- Batch dimensions of inputs to `cdist` must be broadcastable.
- Expected input to have rank >= 2. Received input with shape
- Input should have rank >= 1. Received: input.shape = {x.shap
- Architecture configuration does not match {weights_name} var
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/b4e59a63756435c4.
Report an issue: GitHub.