pandas-dev/pandas · error · TypeError
cannot add the type to a
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-like object (other than Tick or Day, which are handled earlier) to a timedelta64 array. Calendar/anchored offsets (e.g. MonthEnd, YearBegin, BusinessDay) are semantically meaningless when added to a pure duration, so pandas refuses rather than produce a nonsensical result. The assert guards the already-handled Tick/Day case; everything else falls through to the TypeError.
Solutions
- Operate on datetime64 data instead: cast the timedelta to a Timestamp base first, or apply the offset to a DatetimeIndex/Series.
- If the intent is to scale a duration, use an integer/float multiplier rather than a DateOffset.
- For Tick/Day offsets specifically use those types directly, since they are handled by a separate path and will not hit this error.
Example fix
# before
s = pd.Series(pd.to_timedelta([1, 2, 3], unit='D'))
s + pd.offsets.MonthEnd(1) # TypeError
# after (apply offset to datetime data)
ts = pd.Timestamp('2020-01-01')
ts + pd.offsets.MonthEnd(1) Defensive patterns
Strategy: type-guard
Validate before calling
from pandas.tseries.offsets import DateOffset, Tick, Day
def is_offset_addable_to_td(other) -> bool:
# only Tick/Day are addable to timedelta; anything else is rejected
return isinstance(other, (Tick, Day)) or not isinstance(other, DateOffset) Type guard
from pandas.tseries.offsets import DateOffset, Tick, Day
def can_add_to_timedelta(other) -> bool:
"""True if `other` is a valid addend for timedelta64 data."""
if isinstance(other, DateOffset):
return isinstance(other, (Tick, Day))
return True Try / catch
try:
result = td_array + other
except TypeError as e:
if 'cannot add the type' in str(e):
# offset is incompatible with timedelta; route to datetime arithmetic
raise
raise Prevention
- Keep offset arithmetic on datetime64 data; reserve timedelta arithmetic for numeric scaling.
- Guard offset operands with isinstance checks against Tick/Day before adding to timedelta.
When it happens
Trigger: Adding a non-Tick DateOffset to a Series/Index of dtype timedelta64[ns], e.g. `pd.Series(pd.to_timedelta(range(3), unit='D')) + pd.offsets.MonthEnd(1)`, or dispatching `TimedeltaArray.__add__` with an offset operand through the offsets arithmetic path.
Common situations: Mixing offset-based date arithmetic (intended for datetime64) with timedelta64 data; code ported from a Timestamp/TimestampIndex context that reused the same offset operand against durations.
Related errors
- Cannot add or subtract timedelta64[ns] dtype from
- Cannot add/subtract timedelta-like from PeriodArray that is…
- cannot add and
- Cannot divide by
- Cannot multiply ' ' by bool, explicitly cast to integers…
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/730615daf513dd8a.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/timedeltas.py:473
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 3b7651241d)