{"record":{"id":"65dc3e776823b887","repo":"jax-ml/jax","slug":"indexer-must-have-integer-or-boolean-type-got-ind-65dc3e","errorCode":null,"errorMessage":"Indexer must have integer or boolean type, got indexer with type {np.dtype(type(idx))}","messagePattern":"Indexer must have integer or boolean type, got indexer with type (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/indexing.py","lineNumber":104,"sourceCode":"        raise TypeError(\n          f\"Indexer must have integer or boolean type, got indexer with type {idx.dtype}\")\n    elif isinstance(idx, str):\n      # TODO(jakevdp): this TypeError is for backward compatibility.\n      # We should switch to IndexError for consistency.\n      raise TypeError(f\"JAX does not support string indexing; got {idx=}\")\n    elif isinstance(idx, Sequence):\n      if not idx:  # empty indices default to float, so special-case this.\n        return cls.ARRAY\n      idx_aval = api.eval_shape(array_constructors.asarray, idx)\n      if idx_aval.dtype == bool:\n        return cls.BOOLEAN\n      elif dtypes.issubdtype(idx_aval.dtype, np.integer):\n        return cls.ARRAY\n      else:\n        raise TypeError(\n          f\"Indexer must have integer or boolean type, got indexer with type {idx_aval.dtype}\")\n    elif isinstance(idx, (float, complex, np.generic)):\n      raise TypeError(\n        f\"Indexer must have integer or boolean type, got indexer with type {np.dtype(type(idx))}\")\n    else:\n      raise IndexError(\"only integers, slices (`:`), ellipsis (`...`), newaxis (`None`)\"\n                       f\" and integer or boolean arrays are valid indices. Got {idx}\")\n\n\nclass ParsedIndex(NamedTuple):\n  \"\"\"Structure for tracking an indexer parsed within the context of an array shape.\"\"\"\n  index: Index\n  typ: IndexType\n  consumed_axes: tuple[int, ...]\n\n\ndef _parse_indices(\n    indices: tuple[Index, ...],\n    shape: tuple[int, ...],\n) -> list[ParsedIndex]:\n  \"\"\"Parse indices in the context of an array shape.","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/indexing.py#L86-L122","documentation":"IndexType.from_index raises TypeError when the index is a bare Python float, complex, or numpy scalar (np.generic) of non-integer type. JAX refuses float scalar indexing just like modern NumPy. The message shows the dtype inferred from the Python type (e.g. float64).","triggerScenarios":"x[1.0], x[2.5], x[np.float64(3)] — scalar float/complex indices directly inside x[...].","commonSituations":"Values returned from len()/dict lookups/computed positions stored as floats (common when reading JSON config values or dividing counts), then used as indices.","solutions":["Wrap with int(): x[int(pos)]","Fix the source producing floats (e.g. use // instead of / when halving lengths)","Round intentionally if the float came from a real-valued computation: x[int(round(pos))]"],"exampleFix":"// before\nmid = len(xs) / 2\ny = x[mid]\n// after\nmid = len(xs) // 2\ny = x[mid]","handlingStrategy":"type-guard","validationCode":"idx = int(idx) if isinstance(idx, float) else idx","typeGuard":"import operator\ndef is_indexable_scalar(v) -> bool:\n    return isinstance(v, (int, np.integer)) or (hasattr(v, '__index__') and not isinstance(v, float))","tryCatchPattern":null,"preventionTips":["Use // not / when computing positions","Convert config/JSON-sourced numbers with int() at load time"],"tags":["jax","indexing","scalar","dtype"],"backgroundTag":"invalid-index-dtype","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}