{"record":{"id":"0b1e16469b67165f","repo":"pandas-dev/pandas","slug":"cannot-convert-self-dtype-to-dtype-subtypes-a","errorCode":null,"errorMessage":"Cannot convert {self.dtype} to {dtype}; subtypes are incompatible","messagePattern":"Cannot convert (.+?) to (.+?); subtypes are incompatible","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":947,"sourceCode":"            ExtensionArray or NumPy ndarray with 'dtype' for its dtype.\n        \"\"\"\n        from pandas import Index\n\n        if dtype is not None:\n            dtype = pandas_dtype(dtype)\n\n        if isinstance(dtype, IntervalDtype):\n            if dtype == self.dtype:\n                return self.copy() if copy else self\n\n            if is_float_dtype(self.dtype.subtype) and needs_i8_conversion(\n                dtype.subtype\n            ):\n                # This is allowed on the Index.astype but we disallow it here\n                msg = (\n                    f\"Cannot convert {self.dtype} to {dtype}; subtypes are incompatible\"\n                )\n                raise TypeError(msg)\n\n            # need to cast to different subtype\n            try:\n                # We need to use Index rules for astype to prevent casting\n                #  np.nan entries to int subtypes\n                new_left = Index(self._left, copy=False).astype(dtype.subtype)\n                new_right = Index(self._right, copy=False).astype(dtype.subtype)\n            except IntCastingNaNError:\n                # e.g test_subtype_integer\n                raise\n            except (TypeError, ValueError) as err:\n                # e.g. test_subtype_integer_errors f8->u8 can be lossy\n                #  and raises ValueError\n                msg = (\n                    f\"Cannot convert {self.dtype} to {dtype}; subtypes are incompatible\"\n                )\n                raise TypeError(msg) from err\n            return self._shallow_copy(new_left, new_right)","sourceCodeStart":929,"sourceCodeEnd":965,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/interval.py#L929-L965","documentation":"Raised as a TypeError by `IntervalArray.astype` when the current subtype is a float dtype and the target IntervalDtype's subtype is an i8-convertible datetime-like (e.g., `datetime64[ns]` or `timedelta64[ns]`). Casting float NaN positions into i8 datetimes would silently corrupt NaT, so it is disallowed on the array even though `Index.astype` permits it. Fires at pandas/core/arrays/interval.py:947.","triggerScenarios":"`ia.astype('interval[datetime64[ns]]')` where `ia.dtype.subtype` is float64.","commonSituations":"Trying to reinterpret numeric interval bounds (e.g., epoch floats) as datetime intervals in one step.","solutions":["Cast the underlying Index to datetime first: `left = pd.to_datetime(pd.Index(ia.left)); right = pd.to_datetime(pd.Index(ia.right))` then rebuild.","Convert epoch floats via `pd.to_datetime(ia.left, unit='s')`.","Build a fresh `pd.IntervalIndex.from_arrays(left_ts, right_ts, closed=ia.closed)`."],"exampleFix":"// before\nia.astype('interval[datetime64[ns]]')\n// after\nleft = pd.to_datetime(pd.Index(ia.left), unit='s')\nright = pd.to_datetime(pd.Index(ia.right), unit='s')\npd.IntervalIndex.from_arrays(left, right, closed=ia.closed)","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef interval_to_datetime(ia):\n    left = pd.to_datetime(pd.Index(ia.left))\n    right = pd.to_datetime(pd.Index(ia.right))\n    return pd.IntervalIndex.from_arrays(left, right, closed=ia.closed)","typeGuard":"import pandas as pd\nfrom pandas.core.dtypes.common import is_float_dtype\n\ndef is_float_subtype(ia) -> bool:\n    return is_float_dtype(ia.dtype.subtype)","tryCatchPattern":"try:\n    out = ia.astype('interval[datetime64[ns]]')\nexcept TypeError as e:\n    if \"subtypes are incompatible\" in str(e):\n        left = pd.to_datetime(pd.Index(ia.left))\n        right = pd.to_datetime(pd.Index(ia.right))\n        out = pd.IntervalIndex.from_arrays(left, right, closed=ia.closed)\n    else:\n        raise","preventionTips":["Convert numeric epoch bounds to datetime explicitly before building intervals.","Do not rely on IntervalArray.astype to bridge float -> datetime subtypes.","Keep interval subtype transitions within numeric or within datetime-like families."],"tags":["interval","astype","dtype","datetime","casting"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}