pandas-dev/pandas · error · TypeError
Cannot add {type(self).__name__} and {type(NaT).__name__}
Error message
Cannot add {type(self).__name__} and {type(NaT).__name__} What it means
Raised by _add_nat when self.dtype is PeriodDtype. Adding pd.NaT to a PeriodArray is semantically unclear (Period + timedelta shifts by freq multiples, and NaT has no freq), so pandas refuses. For datetime/timedelta dtypes NaT is treated as a timedelta-like and returns all-NaT.
Source
Thrown at pandas/core/arrays/datetimelike.py:1205
"DatetimeArray | TimedeltaArray", self
)._ensure_matching_resos(other)
return self._add_timedeltalike(other)
@final
def _add_timedeltalike(self, other: Timedelta | TimedeltaArray) -> Self:
other_i8, o_mask = self._get_i8_values_and_mask(other)
new_values = add_overflowsafe(self.asi8, np.asarray(other_i8, dtype="i8"))
res_values = new_values.view(self._ndarray.dtype)
return type(self)._simple_new(res_values, dtype=self.dtype)
@final
def _add_nat(self) -> Self:
"""
Add pd.NaT to self
"""
if isinstance(self.dtype, PeriodDtype):
raise TypeError(
f"Cannot add {type(self).__name__} and {type(NaT).__name__}"
)
# GH#19124 pd.NaT is treated like a timedelta for both timedelta
# and datetime dtypes
result = np.empty(self.shape, dtype=np.int64)
result.fill(iNaT)
result = result.view(self._ndarray.dtype) # preserve reso
return type(self)._simple_new(result, dtype=self.dtype)
@final
def _sub_nat(self) -> np.ndarray:
"""
Subtract pd.NaT from self
"""
# GH#19124 Timedelta - datetime is not in general well-defined.
# We make an exception for pd.NaT, which in this case quacks
# like a timedelta.View on GitHub (pinned to 71959b8cb9)
Solutions
- To null out a PeriodIndex elementwise, assign pd.NaT directly via .iloc or use idx.where(cond, other=pd.NaT).
- Convert to datetime if you need NaT arithmetic semantics: idx.to_timestamp() + pd.NaT.
- Add an integer multiple of the freq instead: period_idx + n shifts by n periods.
- Guard on isinstance(idx.dtype, pd.PeriodDtype) before generic NaT addition.
Example fix
// before out = period_idx + pd.NaT # TypeError // after out = period_idx.where(pd.Series([True, False, True]), other=pd.NaT)
Defensive patterns
Strategy: type-guard
Validate before calling
from pandas.api.types import is_period_dtype
if is_period_dtype(idx.dtype):
out = idx.where(pd.Series([True]*len(idx)), other=pd.NaT)
else:
out = idx + pd.NaT Type guard
def rejects_nat_addition(idx) -> bool:
from pandas.api.types import is_period_dtype
return is_period_dtype(idx.dtype) Try / catch
try:
out = idx + pd.NaT
except TypeError as e:
if 'Cannot add' in str(e) and 'NaT' in str(e):
out = idx.where(pd.Series([True]*len(idx)), other=pd.NaT)
else:
raise Prevention
- Do not add pd.NaT to PeriodIndex; assign NaT via where/iloc instead.
- Special-case PeriodDtype in generic NaT-arithmetic helpers.
- Convert Period to timestamp if NaT-as-timedelta semantics are required.
When it happens
Trigger: PeriodIndex + pd.NaT, dispatched via __add__ line 1313 into _add_nat at line 1200; the PeriodDtype check at line 1204 fires.
Common situations: Generic 'fill with NaT' code paths that operate uniformly over Datetime/Timedelta/Period indexes; broadcasting NaT through mixed-dtype dictionaries.
Related errors
- cannot add Period to a {type(self).__name__}
- cannot add {type(self).__name__} and {type(other).__name__}
- cannot subtract {type(other).__name__} from {type(self).__na
- start and end must not be NaT
- Cannot compare types {!r} and {!r}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/5a742b7e4f3b805d.
Report an issue: GitHub.