jax-ml/jax · error · ValueError

ind must be a positive integer; got {ind=}

Error message

ind must be a positive integer; got {ind=}

What it means

jnp.linalg.tensorinv(a, ind) computes the inverse of a tensor by reshaping it to a matrix, splitting a's axes into two groups of length ind and a.ndim-ind. ind must be a positive Python integer (it goes through operator.index). Anything <= 0, or a non-indexable type like a float, fails here or at operator.index.

Source

Thrown at jax/_src/numpy/linalg.py:2098

    array of shape ``(*a.shape[ind:], *a.shape[:ind])`` containing the
    tensor inverse of ``a``.

  See also:
    - :func:`jax.numpy.linalg.tensordot`
    - :func:`jax.numpy.linalg.tensorsolve`

  Examples:
    >>> key = jax.random.key(1337)
    >>> x = jax.random.normal(key, shape=(2, 2, 4))
    >>> xinv = jnp.linalg.tensorinv(x, 2)
    >>> xinv_x = jnp.linalg.tensordot(xinv, x, axes=2)
    >>> jnp.allclose(xinv_x, jnp.eye(4), atol=1E-4)
    Array(True, dtype=bool)
  """
  arr = ensure_arraylike("tensorinv", a)
  ind = operator.index(ind)
  if ind <= 0:
    raise ValueError(f"ind must be a positive integer; got {ind=}")
  contracting_shape, batch_shape = arr.shape[:ind], arr.shape[ind:]
  flatshape = (math.prod(contracting_shape), math.prod(batch_shape))
  if flatshape[0] != flatshape[1]:
    raise ValueError("tensorinv is only possible when the product of the first"
                     " `ind` dimensions equals that of the remaining dimensions."
                     f" got {arr.shape=} with {ind=}.")
  return inv(arr.reshape(flatshape)).reshape(*batch_shape, *contracting_shape)


@export
def tensorsolve(a: ArrayLike, b: ArrayLike, axes: tuple[int, ...] | None = None) -> Array:
  """Solve the tensor equation a x = b for x.

  JAX implementation of :func:`numpy.linalg.tensorsolve`.

  Args:
    a: input array. After reordering via ``axes`` (see below), shape must be
      ``(*b.shape, *x.shape)``.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pass a positive static Python int for ind (typically 2, matching the square tensor convention prod(shape[:ind]) == prod(shape[ind:])).
  2. Mark ind-dependent logic as static or compute ind outside jit.
  3. Validate ind >= 1 at the call site before invoking tensorinv.

Example fix

// before
inv = jnp.linalg.tensorinv(t, ind=0)
// after
inv = jnp.linalg.tensorinv(t, ind=2)
Defensive patterns

Strategy: validation

Validate before calling

ind = int(ind)
assert ind >= 1, f'ind must be >= 1, got {ind}'
inv = jnp.linalg.tensorinv(a, ind=ind)

Type guard

def valid_ind(ind) -> bool:
    return isinstance(ind, (int,)) and not isinstance(ind, bool) and ind >= 1

Prevention

When it happens

Trigger: Calling jnp.linalg.tensorinv(a, ind=0) or a negative ind; passing ind as a tracer value under jit (operator.index raises TracerIntegerConversionError, a sibling failure).

Common situations: Mirroring SciPy's tensorinv API and defaulting ind to 0 (SciPy default is 2); computing ind dynamically inside jitted code; off-by-one when computing the split index from tensor order.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/66759145b25d4a32. Report an issue: GitHub.