{"record":{"id":"cde889c09cac5ecb","repo":"jax-ml/jax","slug":"dynamic-slice-only-unit-steps-supported-in-slice","errorCode":null,"errorMessage":"dynamic_slice: only unit steps supported in slice. Got {pidx.index} at position {position}","messagePattern":"dynamic_slice: only unit steps supported in slice\\. Got (.+?) at position (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/indexing.py","lineNumber":495,"sourceCode":"    if mode is not None:\n      parsed_mode = slicing.GatherScatterMode.from_any(mode)\n      if parsed_mode not in [\n          slicing.GatherScatterMode.PROMISE_IN_BOUNDS, slicing.GatherScatterMode.CLIP]:\n        raise ValueError(\"dynamic_slice requires mode='promise_in_bounds' or mode='clip'\")\n\n    # For sharded inputs, indexing (like x[0]) and partial slices (like x[:2] as\n    # opposed to x[:]) lead to incorrect sharding semantics when computed via slice.\n    # TODO(yashkatariya): fix slice with sharding\n    if arr_is_sharded and self.has_partial_slices():\n      raise ValueError(\"dynamic_slice with partial slices does not support nontrivial array sharding.\")\n\n    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] = []","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/indexing.py#L477-L513","documentation":"Raised by JAX's dynamic-slice index lowering when a jax.indexing.Slice (dynamic slice index) has a stride other than 1. XLA's dynamic_slice primitive only supports unit steps, so non-unit strides cannot be lowered and JAX rejects them early with a TypeError.","triggerScenarios":"Using jax.lax.dynamic_slice or jax.experimental.array_api / jnp indexing with a jax.indexing.Slice(start, stop, stride) where stride != 1, inside code paths that go through rewriting_take/to_dynamic_slice (e.g. XLA-usable index expressions like jnp.ndarray.at or dynamic indexing APIs).","commonSituations":"Porting NumPy code that uses arr[start:stop:2] into JAX's dynamic indexing API; using jax.indexing.Slice with a computed step; batched gather code assumed to support strided windows.","solutions":["Use stride 1 (jax.indexing.Slice(start, stop, 1)) and select every other element afterwards if needed","Replace the strided dynamic slice with a static Python slice arr[start:stop:2] when indices are concrete","Use lax.gather or arr.at[...] with an index array computed via arange(start, stop, step)"],"exampleFix":"// before\nidx = (jax.indexing.Slice(0, 10, 2),)\ny = x[idx]\n// after\nidx = (jax.indexing.Slice(0, 10, 1),)\ny = x[idx][:, ::2]","handlingStrategy":"validation","validationCode":"from jax._src import indexing\nassert isinstance(idx, indexing.Slice) is False or idx.stride == 1, 'stride must be 1'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep dynamic slice strides at 1; do additional striding after slicing","Use static Python slices when bounds are concrete"],"tags":["jax","indexing","slice","stride","dynamic-slice"],"backgroundTag":"unsupported-slice-stride","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}