{"record":{"id":"dda94e0e0f578f32","repo":"keras-team/keras","slug":"expected-a-square-matrix-received-non-square-inpu","errorCode":null,"errorMessage":"Expected a square matrix. Received non-square input with shape {a.shape}","messagePattern":"Expected a square matrix\\. Received non-square input with shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/linalg.py","lineNumber":859,"sourceCode":"            raise ValueError(\n                f\"Expected input to have rank >= 1. Received scalar input {a}.\"\n            )\n\n\ndef _assert_2d(*arrays):\n    for a in arrays:\n        if a.ndim < 2:\n            raise ValueError(\n                \"Expected input to have rank >= 2. \"\n                f\"Received input with shape {a.shape}.\"\n            )\n\n\ndef _assert_square(*arrays):\n    for a in arrays:\n        m, n = a.shape[-2:]\n        if m != n:\n            raise ValueError(\n                \"Expected a square matrix. \"\n                f\"Received non-square input with shape {a.shape}\"\n            )\n\n\ndef _assert_a_b_compat(a, b):\n    if a.ndim == b.ndim:\n        if a.shape[-2] != b.shape[-2]:\n            raise ValueError(\n                \"Incompatible shapes between `a` and `b`. \"\n                \"Expected `a.shape[-2] == b.shape[-2]`. \"\n                f\"Received: a.shape={a.shape}, b.shape={b.shape}\"\n            )\n    elif a.ndim == b.ndim - 1:\n        if a.shape[-1] != b.shape[-1]:\n            raise ValueError(\n                \"Incompatible shapes between `a` and `b`. \"\n                \"Expected `a.shape[-1] == b.shape[-1]`. \"","sourceCodeStart":841,"sourceCodeEnd":877,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/linalg.py#L841-L877","documentation":"Square-matrix Keras ops (cholesky, cholesky_inverse, det, eig, eigh) validate that the last two dimensions of each input are equal. The _assert_square helper unpacks a.shape[-2:] and raises when m != n, so any non-square trailing matrix, even inside a valid batch, is rejected before the op runs.","triggerScenarios":"Calling keras.ops.eigh(x) or keras.ops.cholesky(x) with shape (3, 2) or a batch (B, 4, 5); computing a determinant or eigendecomposition of a matrix built by concatenation or reshaping to non-square; passing the output of a Dense layer with units != input features directly to these ops.","commonSituations":"Computing eigenvalues of a rectangular projection matrix; reusing NumPy code where np.linalg.eig fails similarly after migrating to keras.ops; a whitening/regularization layer calling eigh on activations whose last two dims differ; transposition mistakes leaving shape (m, n) with m != n.","solutions":["Fix the construction of the matrix so the last two axes match, e.g. compute a square covariance via keras.ops.matmul(x, x, transpose_b=True).","Inspect x.shape right before the call and correct upstream reshapes or concatenations that produced a rectangular trailing block.","For PCA-style workflows, operate on the Gram/covariance matrix (n_features, n_features), not the raw (batch, features) data matrix.","Add an explicit assert x.shape[-2] == x.shape[-1] before calling the op so failures surface with your own context."],"exampleFix":"// before\nfrom keras import ops\nx = ops.ones((8, 5, 3))   # batch of 5x3 rectangles\nevals = ops.eig(x)         # ValueError: non-square\n\n// after\nx = ops.ones((8, 5, 3))\ncov = ops.matmul(x, x, transpose_b=True)  # (8, 5, 5), square per batch\nevals = ops.eig(cov)","handlingStrategy":"validation","validationCode":"from keras import ops\n\ndef ensure_square(x):\n    sh = x.shape\n    assert sh[-2] is None or sh[-2] == sh[-1], (\n        f\"expected square trailing dims, got {sh}\")\n    return x\n\nevals = ops.eig(ensure_square(cov))","typeGuard":"import keras\n\ndef is_square_batch(x) -> bool:\n    sh = x.shape\n    return x.ndim >= 2 and sh[-2] is not None and sh[-2] == sh[-1]","tryCatchPattern":null,"preventionTips":["Build square inputs via x @ transpose(x) rather than hand-crafted reshapes.","Unit-test custom layers with rectangular dummy tensors to catch non-square paths early.","Assert squareness in your layer's build() where input shapes are known."],"tags":["keras","linalg","square-matrix","shape-validation","eigendecomposition"],"backgroundTag":"tensor-rank-or-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}