{"record":{"id":"94d6465b17f8bf37","repo":"pandas-dev/pandas","slug":"to-concat-must-have-the-same-dtype","errorCode":null,"errorMessage":"to_concat must have the same dtype","messagePattern":"to_concat must have the same dtype","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/_mixins.py","lineNumber":268,"sourceCode":"    def _concat_same_type(\n        cls,\n        to_concat: Sequence[Self],\n        axis: AxisInt = 0,\n    ) -> Self:\n        \"\"\"\n        Concatenate multiple arrays of this dtype.\n\n        Parameters\n        ----------\n        to_concat : sequence of this type\n\n        Returns\n        -------\n        ExtensionArray\n        \"\"\"\n        if not lib.dtypes_all_equal([x.dtype for x in to_concat]):\n            dtypes = {str(x.dtype) for x in to_concat}\n            raise ValueError(\"to_concat must have the same dtype\", dtypes)\n\n        return super()._concat_same_type(to_concat, axis=axis)\n\n    def searchsorted(\n        self,\n        value: NumpyValueArrayLike | ExtensionArray,\n        side: Literal[\"left\", \"right\"] = \"left\",\n        sorter: NumpySorter | None = None,\n    ) -> npt.NDArray[np.intp] | np.intp:\n        \"\"\"\n        Find indices where elements should be inserted to maintain order.\n\n        Find the indices into a sorted array `self` (a) such that, if the\n        corresponding elements in `value` were inserted before the indices,\n        the order of `self` would be preserved.\n\n        Assuming that `self` is sorted:\n","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/_mixins.py#L250-L286","documentation":"`ValueError('to_concat must have the same dtype', dtypes)` from `NDArrayBackedExtensionArray._concat_same_type`. Despite the method's name, it verifies via `lib.dtypes_all_equal` that every array's dtype string matches, and raises with the set of distinct dtype strings if not. This catches mismatches such as different timezones on DatetimeArray, different units on TimedeltaArray, or different Arrow element types.","triggerScenarios":"`pd.concat([Series(dtype=tz1), Series(dtype=tz2)])` where the dtypes are not string-equal; concatenating TimedeltaArrays of different units; concatenating ArrowExtensionArrays whose pyarrow types differ but share the EA class; calling `cls._concat_same_type([...])` directly with mixed dtypes.","commonSituations":"Concatenating tz-aware datetime Series with different timezones; mixing `timedelta64[ns]` with `timedelta64[s]` (pandas 2.x unit support); concatenating Arrow-backed Series with subtly different pyarrow schemas (e.g. `int32` vs `int64`).","solutions":["Unify dtypes before concatenating: `s1 = s1.astype(s2.dtype)` then `pd.concat([s1, s2])`.","For tz-aware datetimes, normalize timezone: `s1 = s1.dt.tz_convert(s2.dt.tz)`.","For Arrow arrays, unify pyarrow types via `s.astype(pd.ArrowDtype(pa_target_type))` before concat.","If the mismatch is intentional, let pandas route through the generic `concat` path (do not call `_concat_same_type` directly)."],"exampleFix":"// before\npd.concat([s_us, s_s])   # timedelta64[us] vs [s] -> ValueError\n\n// after\npd.concat([s_us.astype('timedelta64[s]'), s_s])","handlingStrategy":"validation","validationCode":"dtypes = {str(a.dtype) for a in to_concat}\nif len(dtypes) > 1:\n    target = next(iter(to_concat)).dtype\n    to_concat = [a.astype(target) for a in to_concat]\nresult = type(to_concat[0])._concat_same_type(to_concat)","typeGuard":"def same_dtype(arrays) -> bool:\n    first = str(arrays[0].dtype)\n    return all(str(a.dtype) == first for a in arrays)","tryCatchPattern":"try:\n    out = cls._concat_same_type(parts)\nexcept ValueError as e:\n    if 'to_concat must have the same dtype' in str(e):\n        target = parts[0].dtype\n        out = cls._concat_same_type([p.astype(target) for p in parts])\n    else:\n        raise","preventionTips":["Unify dtypes (timezone, unit, pyarrow type) before concat","Use top-level pd.concat and let pandas cast, rather than calling _concat_same_type directly"],"tags":["concat","dtype-mismatch","datetime","timedelta","pyarrow"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}