pandas-dev/pandas · error · TypeError

cannot add and

Error message

cannot add {type(self).__name__} and {type(other).__name__}

What it means

Raised by _add_datetimelike_scalar when adding a datetimelike scalar (Timestamp / np.datetime64) to an array whose dtype is not timedelta64 (kind != 'm'). Only TimedeltaArray + datetime yields a meaningful DatetimeArray; adding a datetime to a DatetimeArray or PeriodArray is undefined, so pandas refuses.

Solutions

  1. If you meant to shift datetimes by a duration, add a Timedelta / timedelta64 / TimedeltaIndex instead of a Timestamp.
  2. If you meant to add a duration to a Period index, add a Timedelta or use Period arithmetic appropriate to the freq.
  3. Re-check the type of `other` before the operation; the message reports both type(self) and type(other).

Example fix

// before
res = dta + pd.Timestamp('2020-01-01')  # TypeError

// after
res = dta + pd.Timedelta(days=1)
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd

def shift_datetime_array(dta, other):
    if isinstance(other, (pd.Timedelta, pd.TimedeltaIndex,)) or pd.api.types.is_timedelta64_dtype(getattr(other, 'dtype', None)):
        return dta + other
    raise TypeError('add a Timedelta, not a Timestamp, to a DatetimeArray')

Type guard

import pandas as pd

def is_datetimelike_scalar(v) -> bool:
    return isinstance(v, (pd.Timestamp,)) or hasattr(v, 'dtype') and pd.api.types.is_datetime64_dtype(v.dtype)

def is_duration_operand(other) -> bool:
    return isinstance(other, (pd.Timedelta,)) or hasattr(other, 'dtype') and pd.api.types.is_timedelta64_dtype(other.dtype)

Try / catch

try:
    res = arr + other
except TypeError as e:
    if 'cannot add' in str(e) and 'Datetime' in str(e):
        res = arr + pd.Timedelta(other)  # only if conversion is meaningful
    else:
        raise

Prevention

When it happens

Trigger: DatetimeArray(...) + Timestamp(...); PeriodArray + np.datetime64('...'); any attempt to add a datetime scalar to a non-timedelta datetimelike array via __add__ dispatch.

Common situations: Mis-arithmetic in date math: trying to 'shift' a DatetimeIndex by adding a Timestamp instead of a Timedelta; off-by-type bugs in scheduling code that confuses points and durations.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/8f9b807ee491b7fe. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/datetimelike.py:1047

        """
        Get the int64 values and b_mask to pass to add_overflowsafe.
        """
        if isinstance(other, Period):
            i8values = other.ordinal
            mask = None
        elif isinstance(other, (Timestamp, Timedelta)):
            i8values = other._value
            mask = None
        else:
            # PeriodArray, DatetimeArray, TimedeltaArray
            mask = other._isnan
            i8values = other.asi8
        return i8values, mask

    @final
    def _add_datetimelike_scalar(self, other) -> DatetimeArray:
        if not lib.is_np_dtype(self.dtype, "m"):
            raise TypeError(
                f"cannot add {type(self).__name__} and {type(other).__name__}"
            )

        self = cast("TimedeltaArray", self)

        from pandas.core.arrays import DatetimeArray
        from pandas.core.arrays.datetimes import tz_to_dtype

        assert other is not NaT
        if isna(other):
            # i.e. np.datetime64("NaT")
            # In this case we specifically interpret NaT as a datetime, not
            # the timedelta interpretation we would get by returning self + NaT
            result = self._ndarray + NaT.to_datetime64().astype(f"M8[{self.unit}]")
            # Preserve our resolution
            return DatetimeArray._simple_new(result, dtype=result.dtype)

        other = Timestamp(other)

View on GitHub (pinned to 3b7651241d)