jax-ml/jax · error · ValueError
b matrix must have rank >= 1, got shape {b.shape}
Error message
b matrix must have rank >= 1, got shape {b.shape} What it means
jax/_src/lax/linalg.py:1833 in _lu_solve (public lu_solve). The right-hand side b must be at least rank 1 (a vector). A 0-d scalar b has no axis to solve along, so the ValueError fires immediately before broadcasting logic runs.
Source
Thrown at jax/_src/lax/linalg.py:1833
conj = trans == 2
x = triangular_solve(lu, x, left_side=True, lower=False, transpose_a=True,
conjugate_a=conj)
x = triangular_solve(lu, x, left_side=True, lower=True, unit_diagonal=True,
transpose_a=True, conjugate_a=conj)
_, ind = lax.sort_key_val(permutation, lax.iota('int32', permutation.shape[0]))
x = x[ind, :]
else:
raise ValueError(f"'trans' value must be 0, 1, or 2, got {trans}")
return lax.reshape(x, b.shape)
@api.jit(static_argnums=(3,))
def _lu_solve(lu: Array, permutation: Array, b: Array, trans: int) -> Array:
if len(lu.shape) < 2 or lu.shape[-1] != lu.shape[-2]:
raise ValueError("last two dimensions of LU decomposition must be equal, "
"got shape {}".format(lu.shape))
if len(b.shape) < 1:
raise ValueError("b matrix must have rank >= 1, got shape {}"
.format(b.shape))
# Broadcasting follows NumPy's convention for linalg.solve: the RHS is
# treated as a (batched) vector if the number of dimensions differ by 1.
# Otherwise, broadcasting rules apply.
rhs_vector = lu.ndim == b.ndim + 1
if rhs_vector:
if b.shape[-1] != lu.shape[-1]:
raise ValueError("When LU decomposition matrix and b have the same "
"number of dimensions, last axis of LU decomposition "
"matrix (shape {}) and b array (shape {}) must match"
.format(lu.shape, b.shape))
b = b[..., np.newaxis]
else:
if b.shape[-2] != lu.shape[-1]:
raise ValueError("When LU decomposition matrix and b different "
"numbers of dimensions, last axis of LU decomposition "
"matrix (shape {}) and second to last axis of b array "
"(shape {}) must match"View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Keep b at least 1-d: b = jnp.atleast_1d(b) or b = b[None]
- Replace accidental reductions (e.g. use keepdims=True on sums feeding b)
- Add an assert b.ndim >= 1 during development
Example fix
// before x = jax.lax.linalg.lu_solve(lu, piv, b) # b is 0-d scalar // after x = jax.lax.linalg.lu_solve(lu, piv, jnp.atleast_1d(b))
Defensive patterns
Strategy: validation
Validate before calling
b = jnp.atleast_1d(b)
Type guard
def valid_rhs(b: jax.Array) -> bool:
return b.ndim >= 1 Prevention
- Beware jnp.squeeze collapsing (1,) RHS to scalar
- Use keepdims=True on reductions feeding b
When it happens
Trigger: Calling jax.lax.linalg.lu_solve(lu, permutation, b) with b = jnp.scalar or a Python float, e.g. accidentally reducing b with .sum() or indexing b[i] to a scalar before passing.
Common situations: Loop-refactor bugs where b[i] should be b[i:i+1]; aggressive squeezing (jnp.squeeze) collapsing a (1,) RHS to 0-d; mixing scalar coefficients with matrix solves in solvers for ODE roots.
Related errors
- last two dimensions of LU decomposition must be equal, got s
- When LU decomposition matrix and b have the same number of d
- When LU decomposition matrix and b different numbers of dime
- {name} was requested to map its argument along axis {axis},
- The process id of the current process must be defined.
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/9f037d2a14fd3af7.
Report an issue: GitHub.