pandas-dev/pandas · error · TypeError
cannot add the type {type(other).__name__} to a {type(self).
Error message
cannot add the type {type(other).__name__} to a {type(self).__name__} What it means
Raised by TimedeltaArray._add_offset when an attempt is made to add a DateOffset/Tick-like object that is not handled by the dedicated Tick/Day fast paths. Timedelta + offset is generally undefined (offsets apply to datetimes, not durations), so adding an arbitrary offset to a TimedeltaArray raises TypeError naming both types. The assert at line 455 excludes Tick/Day which have their own handlers.
Source
Thrown at pandas/core/arrays/timedeltas.py:456
return get_format_timedelta64(self, box=True)
def _format_native_types(
self, *, na_rep: str | float = "NaT", date_format=None, **kwargs
) -> npt.NDArray[np.object_]:
from pandas.io.formats.format import get_format_timedelta64
# Relies on TimeDelta._repr_base
formatter = get_format_timedelta64(self, na_rep)
# equiv: np.array([formatter(x) for x in self._ndarray])
# but independent of dimension
return np.frompyfunc(formatter, 1, 1)(self._ndarray)
# ----------------------------------------------------------------
# Arithmetic Methods
def _add_offset(self, other):
assert not isinstance(other, (Tick, Day))
raise TypeError(
f"cannot add the type {type(other).__name__} to a {type(self).__name__}"
)
def _mul_float_overflowsafe(
self, other: float | np.floating | npt.NDArray[np.floating]
) -> Self:
# GH#43178: detect float products that would silently saturate to
# int64.max on the int64 cast below
i8 = self.asi8
self_mask = i8 == iNaT
if self_mask.any():
# zero out NaT positions so they don't trigger the bounds check
i8 = np.where(self_mask, 0, i8)
f_result = i8 * other
nan_mask = np.isnan(f_result)
non_nan = f_result[~nan_mask]
# Compare against 2**63, not i8max: i8max (2**63 - 1) rounds up to
# 2**63 in float64, so a product landing exactly on 2**63 would slipView on GitHub (pinned to 71959b8cb9)
Solutions
- If you want to shift datetimes, convert: apply the offset to a datetime Series instead of a timedelta one.
- If you need to add a Tick (e.g. pd.offsets.Hour(2)), convert it to a Timedelta first: `td_arr + pd.Timedelta(offset)`.
- Re-express the operation: durations add to durations via Timedelta, offsets add to timestamps.
Example fix
# before arr + pd.offsets.MonthEnd(1) # TypeError # after # apply offsets to datetimes, or: arr + pd.Timedelta(days=1)
Defensive patterns
Strategy: type-guard
Validate before calling
import pandas as pd
from pandas._libs.tslibs import Timedelta
from pandas.tseries.offsets import Tick, Day
def add_offset_or_td(td_arr, other):
if isinstance(other, (Tick, Day)):
return td_arr + pd.Timedelta(other)
if isinstance(other, pd.Timestamp):
raise TypeError('add offsets to datetimes, not timedeltas')
return td_arr + other Type guard
import pandas as pd
from pandas.tseries.offsets import Tick, Day
def is_tick_or_timedelta(other) -> bool:
return isinstance(other, (Tick, Day, pd.Timedelta)) Try / catch
try:
return td_arr + other
except TypeError as e:
if 'cannot add the type' in str(e):
return td_arr + pd.Timedelta(other)
raise Prevention
- Apply DateOffsets to datetime columns, not timedelta columns.
- Convert Tick offsets to Timedelta before adding to durations.
- Keep offset arithmetic and duration arithmetic in separate code paths.
When it happens
Trigger: Executing `td_arr + pd.offsets.MonthEnd()` or any `timedelta64 + DateOffset` expression. The dispatcher routes offset addition to _add_offset, which rejects non-Tick offsets.
Common situations: Treating a duration column like a datetime column and shifting by calendar offsets; merging logic that mixes timedelta and offset arithmetic.
Related errors
- Cannot multiply '{self.dtype}' by bool, explicitly cast to i
- Cannot multiply with {type(other).__name__}
- Cannot add or subtract timedelta64[ns] dtype from {self.dtyp
- Cannot add/subtract timedelta-like from PeriodArray that is
- Cannot multiply StringArray by bools. Explicitly cast to int
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/730615daf513dd8a.
Report an issue: GitHub.