{"record":{"id":"5c39aee9369356b5","repo":"pandas-dev/pandas","slug":"invalid-na-position-na-position","errorCode":null,"errorMessage":"invalid na_position: {na_position}","messagePattern":"invalid na_position: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":1521,"sourceCode":"        >>> pd.array([True, False, pd.NA], dtype=\"boolean[pyarrow]\").all(skipna=False)\n        False\n        >>> pd.array([1, 0, pd.NA], dtype=\"boolean[pyarrow]\").all(skipna=False)\n        False\n        \"\"\"\n        return self._reduce(\"all\", skipna=skipna, **kwargs)\n\n    def argsort(\n        self,\n        *,\n        ascending: bool = True,\n        kind: SortKind = \"quicksort\",\n        na_position: str = \"last\",\n        **kwargs,\n    ) -> np.ndarray:\n        order = \"ascending\" if ascending else \"descending\"\n        null_placement = {\"last\": \"at_end\", \"first\": \"at_start\"}.get(na_position, None)\n        if null_placement is None:\n            raise ValueError(f\"invalid na_position: {na_position}\")\n\n        result = pc.array_sort_indices(\n            self._pa_array, order=order, null_placement=null_placement\n        )\n        np_result = result.to_numpy()\n        return np_result.astype(np.intp, copy=False)\n\n    def sort(\n        self,\n        *,\n        ascending: bool = True,\n        kind: SortKind = \"quicksort\",\n        na_position: str = \"last\",\n    ) -> None:\n        # This override replaces self._pa_array directly, bypassing __setitem__,\n        # so enforce the read-only guard here to stay consistent with it and\n        # with the base ExtensionArray.sort.\n        if self._readonly:","sourceCodeStart":1503,"sourceCodeEnd":1539,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L1503-L1539","documentation":"Raised by ArrowExtensionArray.argsort when na_position is not 'last' or 'first'. The mapping dict at line 1519 only accepts those two strings; any other value (typo, 'Last', 'end', None, 'at_end') yields null_placement None and raises ValueError. Used by argsort/sort/sort_values pipelines.","triggerScenarios":"`arr.argsort(na_position='end')`, `arr.argsort(na_position=None)`, `arr.argsort(na_position='LAST')`, or passing a user-controlled config value without validation. Case-sensitive: only lowercase 'first'/'last'.","commonSituations":"Config-driven sort parameters from YAML/JSON where values differ ('at_end', 'tail'); case mismatches; passing pandas-internal null_placement strings ('at_start'/'at_end') that pyarrow uses but argsort doesn't accept at the public API.","solutions":["Use only 'first' or 'last' (lowercase).","Normalize user input: na_position = str(na_position).lower(); assert in {'first','last'}.","Map synonyms: {'at_start':'first','at_end':'last','head':'first','tail':'last'}.","Default to 'last' when input is missing/invalid."],"exampleFix":"# before\nidx = arr.argsort(na_position=cfg.get('na', 'at_end'))  # ValueError\n# after\nNA_MAP = {'at_start':'first','at_end':'last','first':'first','last':'last'}\nna = NA_MAP[str(cfg.get('na','last')).lower()]\nidx = arr.argsort(na_position=na)","handlingStrategy":"validation","validationCode":"VALID_NA_POSITIONS = {'first', 'last'}\nSYNONYMS = {'at_start': 'first', 'at_end': 'last', 'head': 'first', 'tail': 'last', 'top': 'first', 'bottom': 'last'}\n\ndef normalize_na_position(x):\n    if x is None:\n        return 'last'\n    key = str(x).lower()\n    return SYNONYMS.get(key, key) if key in SYNONYMS else (key if key in VALID_NA_POSITIONS else 'last')\n\nna = normalize_na_position(cfg.get('na_position'))\nidx = arr.argsort(na_position=na)","typeGuard":"def is_valid_na_position(x) -> bool:\n    return isinstance(x, str) and x.lower() in {'first', 'last'}","tryCatchPattern":"try:\n    idx = arr.argsort(na_position=na)\nexcept ValueError as e:\n    if 'invalid na_position' in str(e):\n        idx = arr.argsort(na_position='last')\n    else:\n        raise","preventionTips":["Normalize na_position from external config to 'first'/'last' (lowercase).","Validate the value against {'first','last'} before passing.","Map pyarrow-internal synonyms (at_start/at_end) to the public vocabulary."],"tags":["pyarrow","sorting","input-validation","argsort"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}