{"record":{"id":"26d3a71a6780d3e6","repo":"pandas-dev/pandas","slug":"invalid-na-position-na-position-r","errorCode":null,"errorMessage":"invalid na_position: {na_position!r}","messagePattern":"invalid na_position: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/categorical.py","lineNumber":2159,"sourceCode":"        >>> c\n        [NaN, 2, 2, NaN, 5]\n        Categories (2, int64): [2, 5]\n        >>> c.sort_values()\n        [2, 2, 5, NaN, NaN]\n        Categories (2, int64): [2, 5]\n        >>> c.sort_values(ascending=False)\n        [5, 2, 2, NaN, NaN]\n        Categories (2, int64): [2, 5]\n        >>> c.sort_values(na_position=\"first\")\n        [NaN, NaN, 2, 2, 5]\n        Categories (2, int64): [2, 5]\n        >>> c.sort_values(ascending=False, na_position=\"first\")\n        [NaN, NaN, 5, 2, 2]\n        Categories (2, int64): [2, 5]\n        \"\"\"\n        inplace = validate_bool_kwarg(inplace, \"inplace\")\n        if na_position not in [\"last\", \"first\"]:\n            raise ValueError(f\"invalid na_position: {na_position!r}\")\n\n        sorted_idx = nargsort(self, ascending=ascending, na_position=na_position)\n\n        if not inplace:\n            codes = self._codes[sorted_idx]\n            return self._from_backing_data(codes)\n        self._codes[:] = self._codes[sorted_idx]\n        return None\n\n    def _rank(\n        self,\n        *,\n        axis: AxisInt = 0,\n        method: RankMethod = \"average\",\n        na_option: RankNaOption = \"keep\",\n        ascending: bool = True,\n        pct: bool = False,\n    ):","sourceCodeStart":2141,"sourceCodeEnd":2177,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/categorical.py#L2141-L2177","documentation":"Raised inside Categorical.sort_values when the na_position argument is neither 'last' nor 'first'. The argument is validated before nargsort is dispatched because the downstream Cython sort only knows those two sentinel strings. Any other value (including typos, wrong case, or None) is rejected up front.","triggerScenarios":"cat.sort_values(na_position='end'), cat.sort_values(na_position='First') (wrong case), cat.sort_values(na_position=None), cat.sort_values(na_position='top'). Also reached indirectly via DataFrame.sort_values on a categorical column with an invalid na_position.","commonSituations":"User assumes NumPy/SQL vocabulary ('DESC','NULLS FIRST') applies. Copy-pasting from code that used a different library. Passing a variable that was meant to be 'last' but is None due to an unset config.","solutions":["Use na_position='last' (default) or na_position='first' — these are the only accepted values.","Check the variable feeding na_position; default it to 'last' if None.","If building a UI/config layer, validate against {'first','last'} before passing through."],"exampleFix":"# before\ncat.sort_values(na_position='end')  # ValueError\n\n# after\ncat.sort_values(na_position='last')","handlingStrategy":"validation","validationCode":"na_position = na_position or 'last'\nassert na_position in ('first', 'last'), f\"na_position must be 'first' or 'last', got {na_position!r}\"\ncat.sort_values(na_position=na_position)","typeGuard":"def valid_na_position(v: object) -> str:\n    if v not in ('first', 'last'):\n        raise ValueError(f\"na_position must be 'first' or 'last', got {v!r}\")\n    return v  # type: ignore[return-value]","tryCatchPattern":"try:\n    cat.sort_values(na_position=na_pos)\nexcept ValueError as e:\n    if 'invalid na_position' in str(e):\n        cat.sort_values(na_position='last')\n    else:\n        raise","preventionTips":["Default na_position explicitly to 'last' in wrapper functions.","Validate config-driven sort params against {'first','last'} at the config boundary."],"tags":["categorical","sort","argument-validation","na-handling"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}