{"record":{"id":"b4e59a63756435c4","repo":"keras-team/keras","slug":"inputs-to-cdist-must-have-rank-2-received-sh","errorCode":null,"errorMessage":"Inputs to `cdist` must have rank >= 2. Received shapes: x.shape={x.shape}, y.shape={y.shape}","messagePattern":"Inputs to `cdist` must have rank >= 2\\. Received shapes: x\\.shape=(.+?), y\\.shape=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/math.py","lineNumber":380,"sourceCode":"    3.407606\n    \"\"\"\n    if any_symbolic_tensors((x,)):\n        return Logsumexp(axis, keepdims).symbolic_call(x)\n    return backend.math.logsumexp(x, axis=axis, keepdims=keepdims)\n\n\nclass CDist(Operation):\n    def call(self, x, y):\n        diff = backend.numpy.expand_dims(x, -2) - backend.numpy.expand_dims(\n            y, -3\n        )\n        return backend.numpy.sqrt(\n            backend.numpy.sum(backend.numpy.square(diff), axis=-1)\n        )\n\n    def compute_output_spec(self, x, y):\n        if x.ndim < 2 or y.ndim < 2:\n            raise ValueError(\n                \"Inputs to `cdist` must have rank >= 2. \"\n                f\"Received shapes: x.shape={x.shape}, y.shape={y.shape}\"\n            )\n\n        if (\n            x.shape[-1] is not None\n            and y.shape[-1] is not None\n            and x.shape[-1] != y.shape[-1]\n        ):\n            raise ValueError(\n                \"The last dimension of inputs to `cdist` must match. \"\n                f\"Received shapes: x.shape={x.shape}, y.shape={y.shape}\"\n            )\n\n        try:\n            batch_shape = broadcast_shapes(x.shape[:-2], y.shape[:-2])\n        except ValueError:\n            raise ValueError(","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/math.py#L362-L398","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfrom keras import ops\nimport numpy as np\np = np.array([0.0, 0.0])      # shape (2,)\npts = np.random.rand(5, 2)\nd = ops.cdist(p, pts)          # ValueError: p.ndim == 1\n\n// after\np = np.array([0.0, 0.0])\npts = np.random.rand(5, 2)\nd = ops.cdist(ops.reshape(p, (1, -1)), pts)  # shape (1, 5)","handlingStrategy":"validation","validationCode":"from keras import ops\n\ndef as_point_matrix(x):\n    if ops.ndim(x) < 2:\n        x = ops.expand_dims(x, -2)  # (d,) -> (1, d)\n    return x\n\nd = ops.cdist(as_point_matrix(x), as_point_matrix(y))","typeGuard":"import keras\n\ndef cdist_rank_ok(x, y) -> bool:\n    return keras.ops.ndim(x) >= 2 and keras.ops.ndim(y) >= 2","tryCatchPattern":null,"preventionTips":["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."],"tags":["keras","cdist","pairwise-distance","shape-validation","rank-error"],"backgroundTag":"tensor-rank-or-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}