{"record":{"id":"e9a2a611509747c7","repo":"jax-ml/jax","slug":"dynamic-slice-indices-must-be-scalars-or-slices","errorCode":null,"errorMessage":"dynamic_slice: indices must be scalars or slices. Got index of type {type(pidx.index)} at position {position}","messagePattern":"dynamic_slice: indices must be scalars or slices\\. Got index of type (.+?) at position (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/indexing.py","lineNumber":507,"sourceCode":"    for position, pidx in enumerate(self.indices):\n      if pidx.typ in [IndexType.INTEGER, IndexType.ELLIPSIS, IndexType.NONE]:\n        pass\n      elif pidx.typ == IndexType.DYNAMIC_SLICE:\n        assert isinstance(pidx.index, indexing.Slice)\n        if pidx.index.stride != 1:\n          raise TypeError(\"dynamic_slice: only unit steps supported in slice.\"\n                          f\" Got {pidx.index} at position {position}\")\n      elif pidx.typ == IndexType.SLICE:\n        assert isinstance(pidx.index, slice)\n        if pidx.index.step is not None and pidx.index.step not in [-1, 1]:\n          raise TypeError(\"dynamic_slice: only unit steps supported in slice.\"\n                          f\" Got {pidx.index} at position {position}\")\n      elif pidx.typ == IndexType.ARRAY:\n        if isinstance(pidx.index, Sequence) or np.shape(pidx.index) != ():  # pyrefly: ignore[no-matching-overload]\n          raise TypeError(\"dynamic_slice: only scalar indices allowed.\"\n                          f\" Got index of type {type(pidx.index)} at position {position}\")\n      elif pidx.typ == IndexType.BOOLEAN:\n        raise TypeError(\"dynamic_slice: indices must be scalars or slices.\"\n                        f\" Got index of type {type(pidx.index)} at position {position}\")\n      else:\n        raise TypeError(f\"dynamic_slice: unrecognized index {pidx.index} at position {position}.\")\n\n    start_indices: list[ArrayLike] = []\n    slice_sizes: list[int] = []\n    rev_axes: list[int] = []\n    squeeze_axes: list[int] = []\n    newaxis_dims: list[int] = []\n\n    expanded = self.expand_ellipses()\n    trivial_slicing = True\n    for pidx in expanded.indices:\n      if pidx.typ in [IndexType.BOOLEAN, IndexType.ELLIPSIS]:\n        raise RuntimeError(f\"Internal: unexpected index encountered: {pidx}\")\n      elif pidx.typ == IndexType.NONE:\n        # Expanded axes indices are based on the rank of the array after slicing\n        # (tracked by start_indices) and squeezing (tracked by squeeze_axes), and","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/indexing.py#L489-L525","documentation":"Dynamic slicing only accepts integers and slices. Boolean indices (and any index typed BOOLEAN) are rejected here because dynamic_slice cannot represent boolean mask gathers.","triggerScenarios":"Using a boolean array or scalar as an index in the dynamic-slice path, e.g. x.at[bool_tracer].get() or passing a boolean mask where an integer index is expected.","commonSituations":"Reusing a comparison result (arr > 0) as an index in code migrated to dynamic indexing; bool flags accidentally used as positional indices; masks intended for x[mask] boolean indexing.","solutions":["Convert booleans to integers: index = jnp.asarray(mask).astype(jnp.int32) if it encodes positions","Use proper boolean masking x[mask] outside the dynamic-slice path","Use jnp.nonzero(mask) to convert a mask to integer indices first"],"exampleFix":"// before\ny = x.at[some_bool].get()\n// after\ny = x.at[int(some_bool)].get()  # or use x[x > 0] for masks","handlingStrategy":"type-guard","validationCode":"assert not any(isinstance(i, (bool, np.bool_)) or (hasattr(i, 'dtype') and i.dtype == np.bool_) for i in idx_tuple), 'boolean indices unsupported in dynamic slice'","typeGuard":"def is_bool_index(i) -> bool:\n    return isinstance(i, (bool, np.bool_)) or (hasattr(i, 'dtype') and getattr(i.dtype, 'name', '') == 'bool')","tryCatchPattern":null,"preventionTips":["Convert masks with jnp.nonzero(mask) before indexing","Never pass comparison results as positional indices"],"tags":["jax","indexing","boolean-index","dynamic-slice"],"backgroundTag":"invalid-index-type","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}