{"record":{"id":"b1b90873d4c22616","repo":"jax-ml/jax","slug":"name-in-op-name-op-must-not-repeat-got-dims","errorCode":null,"errorMessage":"{name} in {op_name} op must not repeat; got: {dims}.","messagePattern":"(.+?) in (.+?) op must not repeat; got: (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/slicing.py","lineNumber":1804,"sourceCode":"    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}.\")\n\ndef _no_duplicate_dims(dims, op_name, name):\n  if len(set(dims)) != len(dims):\n    raise TypeError(f\"{name} in {op_name} op must not repeat; got: {dims}.\")\n\ndef _disjoint_dims(dims1, dims2, op_name, name1, name2):\n  if not set(dims1).isdisjoint(set(dims2)):\n    raise TypeError(f\"{name1} and {name2} in {op_name} op must be disjoint; \"\n                    f\"got: {dims1} and {dims2}.\")\n\ndef _gather_shape_rule(operand, indices, *, dimension_numbers,\n                       slice_sizes, unique_indices, indices_are_sorted,\n                       mode, fill_value):\n  \"\"\"Validates the well-formedness of the arguments to Gather.\n\n  The code implements the checks based on the detailed operation semantics of\n  XLA's `Gather <https://www.openxla.org/xla/operation_semantics#gather>`_\n  operator and following the outline of the implementation of\n  ShapeInference::InferGatherShape in TensorFlow.\n  \"\"\"\n\n  offset_dims = dimension_numbers.offset_dims","sourceCodeStart":1786,"sourceCodeEnd":1822,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/slicing.py#L1786-L1822","documentation":"Validator used by gather/scatter shape rules that rejects dimension lists containing duplicates: e.g. offset_dims=(1, 1) or update_window_dims=(0, 2, 0). Each dimension may appear at most once in a given list because the maps between input/output axes must be bijective, matching XLA's constraint.","triggerScenarios":"Constructing GatherDimensionNumbers or ScatterDimensionNumbers where a dim list repeats a value, then calling lax.gather or lax.scatter/update with those numbers.","commonSituations":"Programmatic generation of dim lists (nested loops appending indices twice); merging configs from two call sites; off-by-one when slicing a range producing repeated axes (e.g. [i, i] from range closures).","solutions":["De-duplicate and re-sort the offending list: dims = tuple(sorted(set(dims))).","Audit the loop/comprehension that builds the dim list for double insertion.","Prefer jnp.take / x.at[idx].set() which never need manual dim lists."],"exampleFix":"# before\ndnums = lax.GatherDimensionNumbers(\n    offset_dims=(1, 1), collapsed_slice_dims=(0,), start_index_map=(0,))\nout = lax.gather(x, idx, dnums, slice_sizes=(1,))  # duplicate dim -> TypeError\n\n# after\ndnums = lax.GatherDimensionNumbers(\n    offset_dims=(0, 1), collapsed_slice_dims=(), start_index_map=(0,))\nout = lax.gather(x, idx, dnums, slice_sizes=(1, 1))","handlingStrategy":"validation","validationCode":"offset_dims = tuple(sorted(set(offset_dims)))\nupdate_window_dims = tuple(sorted(set(update_window_dims)))","typeGuard":"def has_no_duplicates(dims: tuple) -> bool:\n    return len(set(dims)) == len(dims)","tryCatchPattern":null,"preventionTips":["Apply tuple(sorted(set(...))) to every programmatically built dim list.","Lint dim-list construction loops for accidental double appends.","Use jnp.take / x.at[] instead of hand-written dnums where possible."],"tags":["jax","lax","gather","scatter","duplicate-dims"],"backgroundTag":"duplicate-dimension-in-config","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}