pandas-dev/pandas · error · ValueError
to_concat must have the same dtype
Error message
to_concat must have the same dtype
What it means
`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.
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).
Example fix
// before
pd.concat([s_us, s_s]) # timedelta64[us] vs [s] -> ValueError
// after
pd.concat([s_us.astype('timedelta64[s]'), s_s]) Defensive patterns
Strategy: validation
Validate before calling
dtypes = {str(a.dtype) for a in to_concat}
if len(dtypes) > 1:
target = next(iter(to_concat)).dtype
to_concat = [a.astype(target) for a in to_concat]
result = type(to_concat[0])._concat_same_type(to_concat) Type guard
def same_dtype(arrays) -> bool:
first = str(arrays[0].dtype)
return all(str(a.dtype) == first for a in arrays) Try / catch
try:
out = cls._concat_same_type(parts)
except ValueError as e:
if 'to_concat must have the same dtype' in str(e):
target = parts[0].dtype
out = cls._concat_same_type([p.astype(target) for p in parts])
else:
raise Prevention
- Unify dtypes (timezone, unit, pyarrow type) before concat
- Use top-level pd.concat and let pandas cast, rather than calling _concat_same_type directly
When it happens
Trigger: `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.
Common situations: 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`).
Related errors
- Can only use the '.list' accessor with 'list[pyarrow]'…
- Can only use the '.struct' accessor with 'struct[pyarrow]'…
- cannot add and
- DateOffset is intra-day and cannot be applied to…
- dtype cannot be converted to datetime64[ns]
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/94d6465b17f8bf37.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/_mixins.py:268
def _concat_same_type(
cls,
to_concat: Sequence[Self],
axis: AxisInt = 0,
) -> Self:
"""
Concatenate multiple arrays of this dtype.
Parameters
----------
to_concat : sequence of this type
Returns
-------
ExtensionArray
"""
if not lib.dtypes_all_equal([x.dtype for x in to_concat]):
dtypes = {str(x.dtype) for x in to_concat}
raise ValueError("to_concat must have the same dtype", dtypes)
return super()._concat_same_type(to_concat, axis=axis)
def searchsorted(
self,
value: NumpyValueArrayLike | ExtensionArray,
side: Literal["left", "right"] = "left",
sorter: NumpySorter | None = None,
) -> npt.NDArray[np.intp] | np.intp:
"""
Find indices where elements should be inserted to maintain order.
Find the indices into a sorted array `self` (a) such that, if the
corresponding elements in `value` were inserted before the indices,
the order of `self` would be preserved.
Assuming that `self` is sorted:
View on GitHub (pinned to 3b7651241d)