{"record":{"id":"c73ba75c09f27cbb","repo":"keras-team/keras","slug":"incompatible-shapes-between-a-and-b-expected-c73ba7","errorCode":null,"errorMessage":"Incompatible shapes between `a` and `b`. Expected `a.shape[-1] == b.shape[-1]`. Received: a.shape={a.shape}, b.shape={b.shape}","messagePattern":"Incompatible shapes between `a` and `b`\\. Expected `a\\.shape\\[-1\\] == b\\.shape\\[-1\\]`\\. Received: a\\.shape=(.+?), b\\.shape=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/linalg.py","lineNumber":875,"sourceCode":"        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]`. \"\n                f\"Received: a.shape={a.shape}, b.shape={b.shape}\"\n            )\n\n\nclass JVP(Operation):\n    def __init__(self, has_aux=False, *, name=None):\n        super().__init__(name=name)\n        self.has_aux = has_aux\n\n    def call(self, fun, primals, tangents):\n        \"\"\"Computes the JVP of `fun` at `primals` along `tangents`.\n\n        Args:\n            fun: A callable that takes tensors (or nested structures) as input\n                 and returns a tensor (or nested structure) as output.\n            primals: Input tensors (or nested structures) at which the Jacobian","sourceCodeStart":857,"sourceCodeEnd":893,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/linalg.py#L857-L893","documentation":"In the rank(a) == rank(b) - 1 branch of _assert_a_b_compat, keras.ops.solve / keras.ops.solve_triangular treat b as a batch of vectors and require a.shape[-1] == b.shape[-1]: the number of unknowns must equal the length of each RHS vector. This error means the coefficient matrix's column count differs from the right-hand-side vector length.","triggerScenarios":"Calling keras.ops.solve(A, b) with A of shape (3, 3) and b of shape (4,) (rank differs by one), or batched A (B, 5, 5) with vectors b of shape (B, 4); using solve_triangular with a factor of size n but an RHS vector of length m != n.","commonSituations":"Solving square systems where the RHS was assembled from a different feature dimension; migrating from np.linalg.solve where NumPy raises its own mismatch error, making the Keras requirement non-obvious; feeding flattened labels of the wrong length as b.","solutions":["Align dimensions: build b with b.shape[-1] == a.shape[-1]; for multiple RHS use shape (n, k) so ranks match and the row rule applies.","Audit where b is produced and ensure it is not a slice/padding artifact with a different length than the system size.","Add a pre-call check: assert a.shape[-1] == b.shape[-1] (vector case) or a.shape[-2] == b.shape[-2] (matrix case)."],"exampleFix":"// before\nfrom keras import ops\nimport numpy as np\nA = np.random.rand(5, 5)\nb = np.random.rand(7)     # length 7, but 5 unknowns\nx = ops.solve(A, b)       # ValueError\n\n// after\nA = np.random.rand(5, 5)\nb = np.random.rand(5)     # one entry per unknown\nx = ops.solve(A, b)","handlingStrategy":"validation","validationCode":"from keras import ops\n\ndef check_solve_vector_case(a, b):\n    if a.ndim == b.ndim - 1:\n        sa, sb = ops.shape(a)[-1], ops.shape(b)[-1]\n        assert sa is None or sb is None or sa == sb, (\n            f\"a.shape[-1]={sa} != b.shape[-1]={sb}\")\n\ncheck_solve_vector_case(A, b)\nx = ops.solve(A, b)","typeGuard":"def vector_rhs_matches(a, b) -> bool:\n    return a.ndim == b.ndim - 1 and (\n        a.shape[-1] is None or b.shape[-1] is None or a.shape[-1] == b.shape[-1]\n    )","tryCatchPattern":null,"preventionTips":["Prefer a matrix RHS (n, k) over a vector RHS to hit the clearer row rule.","Assemble b from the same code that sizes A.","Add shape asserts in custom layer call() before solve."],"tags":["keras","linalg","linear-solve","shape-validation","solver"],"backgroundTag":"tensor-rank-or-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}