{"record":{"id":"55f69b74812de448","repo":"pandas-dev/pandas","slug":"only-integers-slices-ellipsis-num","errorCode":null,"errorMessage":"only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices","messagePattern":"only integers, slices \\(`:`\\), ellipsis \\(`\\.\\.\\.`\\), numpy\\.newaxis \\(`None`\\) and integer or boolean arrays are valid indices","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":908,"sourceCode":"                return self.take(item)\n            elif item.dtype.kind == \"b\":\n                return self._from_pyarrow_array(self._pa_array.filter(item))\n            else:\n                raise IndexError(\n                    \"Only integers, slices and integer or \"\n                    \"boolean arrays are valid indices.\"\n                )\n        elif isinstance(item, tuple):\n            item = unpack_tuple_and_ellipses(item)\n\n        if item is Ellipsis:\n            # TODO: should be handled by pyarrow?\n            item = slice(None)\n\n        if is_scalar(item) and not is_integer(item):\n            # e.g. \"foo\" or 2.5\n            # exception message copied from numpy\n            raise IndexError(\n                r\"only integers, slices (`:`), ellipsis (`...`), numpy.newaxis \"\n                r\"(`None`) and integer or boolean arrays are valid indices\"\n            )\n        # We are not an array indexer, so maybe e.g. a slice or integer\n        # indexer. We dispatch to pyarrow.\n        value = self._pa_array[item]\n        if isinstance(value, pa.ChunkedArray):\n            result = self._from_pyarrow_array(value)\n            if getitem_returns_view(self, item):\n                result._readonly = self._readonly\n            return result\n        else:\n            pa_type = self._pa_array.type\n            scalar = value.as_py()\n            if scalar is None:\n                return self._dtype.na_value\n            elif pa.types.is_timestamp(pa_type) and pa_type.unit != \"ns\":\n                # GH 53326","sourceCodeStart":890,"sourceCodeEnd":926,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L890-L926","documentation":"Raised by ArrowExtensionArray.__getitem__ when the indexer is scalar but not an integer (e.g. a string label, a float like 2.5). The guard at line 905 explicitly checks `is_scalar(item) and not is_integer(item)` and raises with a numpy-style message. Positional indexing on ArrowExtensionArray requires integer positions; label-based access must go through .loc.","triggerScenarios":"Indexing positionally with a label: `s_arr['a']` on an ArrowExtensionArray, or `s_arr[2.0]`. Floating scalar indices. Also passing an Ellipsis-wrapped tuple that collapses to a non-int scalar.","commonSituations":"Treating an ExtensionArray like a Series (which supports label indexing), or assuming integer-valued floats round. Common when migrating numpy-backed code where `arr[2.0]` silently truncated to `arr[2]`.","solutions":["Use an explicit int: s_arr[int(idx)].","For label access go through the Series: series.loc['a'].","Validate indices: int_idx = operator.index(idx) before indexing.","If idx is a numpy scalar, cast: s_arr[int(idx.item())]."],"exampleFix":"# before\nval = arrow_arr['field_a']   # IndexError: scalar non-int\nval = arrow_arr[2.0]         # IndexError\n# after\nval = series.loc['field_a']  # label access\nval = arrow_arr[int(2.0)]    # positional int","handlingStrategy":"validation","validationCode":"import operator\n\ndef safe_scalar_get(arr, item):\n    if isinstance(item, str):\n        raise IndexError('use Series.loc for label access')\n    try:\n        item = operator.index(item)\n    except TypeError as e:\n        raise IndexError(f'non-integer scalar index {item!r}') from e\n    return arr[item]\n\nval = safe_scalar_get(arrow_arr, idx)","typeGuard":"import numbers\n\ndef is_integer_scalar_index(x) -> bool:\n    return isinstance(x, numbers.Integral) and not isinstance(x, bool)","tryCatchPattern":"try:\n    val = arrow_arr[key]\nexcept IndexError as e:\n    if 'only integers' in str(e):\n        # route label access through Series\n        val = pd.Series(arrow_arr).loc[key]\n    else:\n        raise","preventionTips":["Distinguish label access (.loc) from positional access (.iloc/int) explicitly.","Use operator.index(x) to validate/coerce integer positions.","Avoid floats as positional indices; cast to int."],"tags":["pyarrow","indexing","scalar","label-vs-position"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}