{"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":"validation","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/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/interval.py#L929-L965","documentation":"Raised in IntervalArray.astype when the target dtype is an IntervalDtype, the current subtype is floating, and the target subtype requires i8 (datetime-like) conversion. Reinterpreting float bounds as timestamps is allowed on IntervalIndex.astype but explicitly disallowed at the array level to avoid ambiguous casts.","triggerScenarios":"float_backed_arr.astype('interval[datetime64[ns]]'); arr.astype(IntervalDtype('datetime64[ns]')) on a float-backed IntervalArray; arr.astype('interval[timedelta64[ns]]') from float subtype.","commonSituations":"Reinterpreting numeric interval bounds as timestamps after dtype inference produced floats; mixing time-based and numeric interval pipelines.","solutions":["Route through IntervalIndex if datetime semantics are genuinely required: pd.IntervalIndex(arr).astype(target).","Cast endpoint Indexes to datetime explicitly, then rebuild the IntervalArray.","Keep a numeric target subtype (float/integer) compatible with the float source."],"exampleFix":"// before\narr.astype('interval[datetime64[ns]]')\n// after\nimport pandas as pd\npd.IntervalIndex(arr).astype('interval[datetime64[ns]]')","handlingStrategy":"validation","validationCode":"from pandas.api.types import is_float_dtype, pandas_dtype\nfrom pandas.core.dtypes.common import needs_i8_conversion\n\ndef interval_astype_safe(arr, target):\n    t = pandas_dtype(target)\n    from pandas import IntervalDtype\n    if isinstance(t, IntervalDtype) and is_float_dtype(arr.dtype.subtype) and needs_i8_conversion(t.subtype):\n        raise ValueError('Use IntervalIndex.astype for float->datetime-like interval casts')\n    return arr.astype(t)","typeGuard":null,"tryCatchPattern":"try:\n    arr.astype(target)\nexcept TypeError as e:\n    if 'subtypes are incompatible' in str(e):\n        # route through IntervalIndex or pick a numeric subtype\n        pass\n    else:\n        raise","preventionTips":["Inspect arr.dtype.subtype before astype to an IntervalDtype target.","Remember IntervalIndex.astype permits casts that IntervalArray.astype rejects.","Avoid reinterpreting float bounds as datetime-like at the array level."],"tags":["interval-array","astype","subtype","datetime"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}