{"record":{"id":"36939e094b63b713","repo":"jax-ml/jax","slug":"name-in-op-name-op-must-be-sorted-got-dims","errorCode":null,"errorMessage":"{name} in {op_name} op must be sorted; got {dims}","messagePattern":"(.+?) in (.+?) op must be sorted; got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/slicing.py","lineNumber":1782,"sourceCode":"  aval_out, = ctx.avals_out\n  out = mlir.dynamic_update_slice(ctx, aval_out, x, update,\n                                  start_indices=start_indices)\n  return [mlir.lower_with_sharding_in_types(ctx, out, aval_out)]\n\nmlir.register_lowering(dynamic_update_slice_p, _dynamic_update_slice_lower)\n\n\ndef _gather_dtype_rule(operand, indices, *, fill_value, **kwargs):\n  if not dtypes.issubdtype(indices.dtype, np.integer):\n    raise ValueError(\"indices must have an integer type\")\n  return operand.dtype\n\n_rank = lambda arr: len(arr.shape)\n\ndef _is_sorted(dims, op_name, name):\n  for i in range(1, len(dims)):\n    if dims[i] < dims[i - 1]:\n      raise TypeError(f\"{name} in {op_name} op must be sorted; got {dims}\")\n\ndef _dims_in_range(dims, rank, op_name, name):\n  for dim in dims:\n    if dim < 0 or dim >= rank:\n      raise TypeError(f\"Invalid {name} set in {op_name} op; valid range is \"\n                      f\"[0, {rank}); got: {dim}.\")\n\ndef _sorted_dims_in_range(dims, rank, op_name, name):\n  if len(dims) == 0:\n    return\n  invalid_dim = None\n  if dims[0] < 0:\n    invalid_dim = dims[0]\n  elif dims[-1] >= rank:\n    invalid_dim = dims[-1]\n  if invalid_dim:\n    raise TypeError(f\"Invalid {name} set in {op_name} op; valid range is \"\n                    f\"[0, {rank}); got: {invalid_dim}.\")","sourceCodeStart":1764,"sourceCodeEnd":1800,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/slicing.py#L1764-L1800","documentation":"Helper validator used by the gather/scatter shape rules: dimension lists such as offset_dims, collapsed_slice_dims, start_index_map, or update_window_dims must be given in sorted (ascending) order. If any later element is smaller than the previous one, this TypeError names the offending list. JAX requires sorted lists rather than silently sorting them, to match XLA semantics.","triggerScenarios":"Building lax.GatherDimensionNumbers or lax.ScatterDimensionNumbers by hand with an unsorted tuple, e.g. offset_dims=(2, 0) or start_index_map=(3, 1), then calling lax.gather/lax.scatter with those dimension numbers.","commonSituations":"Hand-rolling embedding lookups or scatter updates instead of jnp.take / .at[]; porting XLA or TensorFlow gather semantics where dims were listed in a different order; dynamically generating dimension numbers with a loop that appends out of order.","solutions":["Sort the listed dims before constructing the dimension numbers: offset_dims=tuple(sorted(offset_dims)).","Prefer higher-level APIs (jnp.take, jnp.take_along_axis, x.at[idx].set(y)) which build dimension numbers for you.","Double-check each list in GatherDimensionNumbers/ScatterDimensionNumbers against the docstring ordering requirement."],"exampleFix":"# before\ndnums = lax.GatherDimensionNumbers(\n    offset_dims=(2, 0), collapsed_slice_dims=(1,), start_index_map=(0, 1))\nout = lax.gather(x, idx, dnums, slice_sizes=(1, 3))  # TypeError\n\n# after\ndnums = lax.GatherDimensionNumbers(\n    offset_dims=(0, 2), collapsed_slice_dims=(1,), start_index_map=(0, 1))\nout = lax.gather(x, idx, dnums, slice_sizes=(1, 3))","handlingStrategy":"validation","validationCode":"offset_dims = tuple(sorted(offset_dims))\ncollapsed_slice_dims = tuple(sorted(collapsed_slice_dims))\nstart_index_map = tuple(sorted(start_index_map))\ndnums = lax.GatherDimensionNumbers(offset_dims, collapsed_slice_dims, start_index_map)","typeGuard":"def dims_are_sorted(dims: tuple) -> bool:\n    return all(dims[i] >= dims[i-1] for i in range(1, len(dims)))","tryCatchPattern":null,"preventionTips":["Always construct dim tuples via tuple(sorted(...)) when built dynamically.","Prefer jnp.take / x.at[idx] APIs that generate dimension numbers internally.","Add a unit test over all dnums configs your library exposes."],"tags":["jax","lax","gather","scatter","dimension-numbers"],"backgroundTag":"dimension-list-not-sorted","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}