{"record":{"id":"9fa6f413ca718079","repo":"pandas-dev/pandas","slug":"cannot-convert-na-to-integer","errorCode":null,"errorMessage":"cannot convert NA to integer","messagePattern":"cannot convert NA to integer","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":805,"sourceCode":"        if isinstance(dtype, ExtensionDtype):\n            eacls = dtype.construct_array_type()\n            return eacls._from_sequence(self, dtype=dtype, copy=copy)\n\n        na_value: float | np.datetime64 | lib.NoDefault\n\n        # coerce\n        if dtype.kind == \"f\":\n            # In astype, we consider dtype=float to also mean na_value=np.nan\n            na_value = np.nan\n        elif dtype.kind == \"M\":\n            unit = np.datetime_data(dtype)[0]\n            na_value = np.datetime64(\"NaT\", unit)  # type: ignore[call-overload]\n        else:\n            na_value = lib.no_default\n\n        # to_numpy will also raise, but we get somewhat nicer exception messages here\n        if dtype.kind in \"iu\" and self._hasna:\n            raise ValueError(\"cannot convert NA to integer\")\n        if dtype.kind == \"b\" and self._hasna:\n            # careful: astype_nansafe converts np.nan to True\n            raise ValueError(\"cannot convert float NaN to bool\")\n\n        data = self.to_numpy(dtype=dtype, na_value=na_value, copy=copy)\n        return data\n\n    __array_priority__ = 1000  # higher than ndarray so ops dispatch to us\n\n    def __array__(\n        self, dtype: NpDtype | None = None, copy: bool | None = None\n    ) -> np.ndarray:\n        \"\"\"\n        the array interface, return my values\n        We return an object array here to preserve our scalar values\n        \"\"\"\n        if copy is False:\n            if not self._hasna:","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/masked.py#L787-L823","documentation":"Raised by BaseMaskedArray._astype when casting a masked array containing missing values to an integer numpy dtype. NumPy integer arrays cannot represent NaN/NA, so pandas raises instead of silently producing garbage. This is the friendly upstream message; to_numpy would raise later with a worse one.","triggerScenarios":"Calling arr.astype('int64'), arr.astype(np.int32), or Series.astype('Int64' -> 'int64') on a masked array whose self._hasna is True. Equivalent path through np.asarray with an int dtype.","commonSituations":"Reading dirty CSV/data where NaNs appear in a numeric column typed as integer; converting a nullable Int64 column to plain numpy int64 for a library that does not accept NaN; chaining dropna incorrectly.","solutions":["Fill or drop missing values before casting: arr.fillna(0).astype('int64') or df.dropna(subset=['col']).astype({'col':'int64'}).","Cast to a nullable integer dtype instead: arr.astype('Int64').","Cast to float64 if NaN must be preserved: arr.astype('float64').","Pass an na_value if going through to_numpy directly."],"exampleFix":"// before\ns.astype(\"int64\")  # raises: cannot convert NA to integer\n\n// after\ns.fillna(0).astype(\"int64\")","handlingStrategy":"validation","validationCode":"def safe_int_cast(arr):\n    if getattr(arr, \"_hasna\", False):\n        raise ValueError(\"array has NA; fill or drop before casting to integer\")\n    return arr.astype(\"int64\")","typeGuard":"def is_na_free(arr) -> bool:\n    return not getattr(arr, \"_hasna\", False)","tryCatchPattern":"try:\n    out = arr.astype(\"int64\")\nexcept ValueError as e:\n    if \"cannot convert NA to integer\" in str(e):\n        out = arr.fillna(0).astype(\"int64\")\n    else:\n        raise","preventionTips":["Run df['col'].isna().any() before integer casts.","Use nullable Int64 when NaN semantics must be preserved.","Centralize integer-cast logic behind a helper that handles NA."],"tags":["masked-array","astype","missing-values","integer"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}