{"record":{"id":"66759145b25d4a32","repo":"jax-ml/jax","slug":"ind-must-be-a-positive-integer-got-ind","errorCode":null,"errorMessage":"ind must be a positive integer; got {ind=}","messagePattern":"ind must be a positive integer; got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/linalg.py","lineNumber":2098,"sourceCode":"    array of shape ``(*a.shape[ind:], *a.shape[:ind])`` containing the\n    tensor inverse of ``a``.\n\n  See also:\n    - :func:`jax.numpy.linalg.tensordot`\n    - :func:`jax.numpy.linalg.tensorsolve`\n\n  Examples:\n    >>> key = jax.random.key(1337)\n    >>> x = jax.random.normal(key, shape=(2, 2, 4))\n    >>> xinv = jnp.linalg.tensorinv(x, 2)\n    >>> xinv_x = jnp.linalg.tensordot(xinv, x, axes=2)\n    >>> jnp.allclose(xinv_x, jnp.eye(4), atol=1E-4)\n    Array(True, dtype=bool)\n  \"\"\"\n  arr = ensure_arraylike(\"tensorinv\", a)\n  ind = operator.index(ind)\n  if ind <= 0:\n    raise ValueError(f\"ind must be a positive integer; got {ind=}\")\n  contracting_shape, batch_shape = arr.shape[:ind], arr.shape[ind:]\n  flatshape = (math.prod(contracting_shape), math.prod(batch_shape))\n  if flatshape[0] != flatshape[1]:\n    raise ValueError(\"tensorinv is only possible when the product of the first\"\n                     \" `ind` dimensions equals that of the remaining dimensions.\"\n                     f\" got {arr.shape=} with {ind=}.\")\n  return inv(arr.reshape(flatshape)).reshape(*batch_shape, *contracting_shape)\n\n\n@export\ndef tensorsolve(a: ArrayLike, b: ArrayLike, axes: tuple[int, ...] | None = None) -> Array:\n  \"\"\"Solve the tensor equation a x = b for x.\n\n  JAX implementation of :func:`numpy.linalg.tensorsolve`.\n\n  Args:\n    a: input array. After reordering via ``axes`` (see below), shape must be\n      ``(*b.shape, *x.shape)``.","sourceCodeStart":2080,"sourceCodeEnd":2116,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/linalg.py#L2080-L2116","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Pass a positive static Python int for ind (typically 2, matching the square tensor convention prod(shape[:ind]) == prod(shape[ind:])).","Mark ind-dependent logic as static or compute ind outside jit.","Validate ind >= 1 at the call site before invoking tensorinv."],"exampleFix":"// before\ninv = jnp.linalg.tensorinv(t, ind=0)\n// after\ninv = jnp.linalg.tensorinv(t, ind=2)","handlingStrategy":"validation","validationCode":"ind = int(ind)\nassert ind >= 1, f'ind must be >= 1, got {ind}'\ninv = jnp.linalg.tensorinv(a, ind=ind)","typeGuard":"def valid_ind(ind) -> bool:\n    return isinstance(ind, (int,)) and not isinstance(ind, bool) and ind >= 1","tryCatchPattern":null,"preventionTips":["Default ind to 2 like SciPy conventions","Keep ind a static Python int outside jit"],"tags":["jax","scipy","linalg","tensor","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}