{"record":{"id":"fbf62ca719e58c60","repo":"jax-ml/jax","slug":"dimension-must-be-either-2-or-3-for-cross-product","errorCode":null,"errorMessage":"Dimension must be either 2 or 3 for cross product","messagePattern":"Dimension must be either 2 or 3 for cross product","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/lax_numpy.py","lineNumber":8031,"sourceCode":"\n    >>> a = jnp.array([[1, 2, 3],\n    ...                [3, 4, 3]])\n    >>> b = jnp.array([[2, 3, 2],\n    ...                [4, 5, 6]])\n    >>> jnp.cross(a, b)\n    Array([[-5,  4, -1],\n           [ 9, -6, -1]], dtype=int32)\n  \"\"\"\n  util.check_arraylike(\"cross\", a, b)\n  if axis is not None:\n    axisa = axis\n    axisb = axis\n    axisc = axis\n  a = moveaxis(a, axisa, -1)\n  b = moveaxis(b, axisb, -1)\n\n  if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3):\n    raise ValueError(\"Dimension must be either 2 or 3 for cross product\")\n\n  if a.shape[-1] == 2 or b.shape[-1] == 2:\n    deprecations.warn(\n        \"jax-numpy-cross-2d-input\",\n        \"Support for 2-dimensional vectors in jnp.cross is deprecated and \"\n        \"will be removed in JAX 0.12.0. Use arrays of 3-dimensional \"\n        \"vectors instead.\",\n        stacklevel=2,\n    )\n\n  if a.shape[-1] == 2 and b.shape[-1] == 2:\n    return a[..., 0] * b[..., 1] - a[..., 1] * b[..., 0]\n\n  a0 = a[..., 0]\n  a1 = a[..., 1]\n  a2 = a[..., 2] if a.shape[-1] == 3 else array_creation.zeros_like(a0)\n  b0 = b[..., 0]\n  b1 = b[..., 1]","sourceCodeStart":8013,"sourceCodeEnd":8049,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/lax_numpy.py#L8013-L8049","documentation":"Raised by jnp.cross when, after moving the specified axes to the last position, either input's last dimension is not 2 or 3 — cross products are only defined for 2-D and 3-D vectors in JAX.","triggerScenarios":"jnp.cross(a, b) where a.shape[-1] is 1, 4, or the arrays are scalars/empty on the last axis; wrong axisa/axisb so a non-vector axis ends up last; passing stacked matrices whose leading dim is misinterpreted.","commonSituations":"Using axis=0 with column-stacked data so shape[-1] != 2/3; passing 4-D homogeneous coordinates; porting code that used scipy cross-free helpers.","solutions":["Fix axisa/axisb (or axis) so the vector dimension (2 or 3) is the axis used","Slice/pad inputs to exactly 2 or 3 components (e.g. pad 2-D to 3-D with zeros)","Ensure inputs are at least 1-D with shape[-1] in (2, 3) before calling"],"exampleFix":"// before\njnp.cross(a, b, axis=0)  # data stacked as (3, N), axis=-1 intended\n// after\njnp.cross(a, b, axis=0)  # verify shape[0] == 3; or transpose: jnp.cross(a.T, b.T)\n","handlingStrategy":"validation","validationCode":"assert a.shape[axisa] in (2, 3) and b.shape[axisb] in (2, 3)","typeGuard":"def crossable(a, b, axisa=-1, axisb=-1):\n    return jnp.moveaxis(a, axisa, -1).shape[-1] in (2, 3) and jnp.moveaxis(b, axisb, -1).shape[-1] in (2, 3)","tryCatchPattern":null,"preventionTips":["Verify vector components (2 or 3) sit on the axis passed to jnp.cross","Pad 2-D vectors to 3-D to avoid the deprecation too","Avoid 4-D homogeneous coordinates with cross"],"tags":["jax","cross-product","shape-validation"],"backgroundTag":"vector-dimension-validation","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}