pandas-dev/pandas · error · TypeError

value should be a ' ' or 'NaT'. Got instead.

Error message

value should be a '{self._scalar_type.__name__}' or 'NaT'. Got {msg_got} instead.

What it means

Raised in DatetimeLikeArray._validate_scalar (allow_listlike=False branch) when value is a string that fails to parse as the expected scalar type (e.g., a malformed date string passed to a DatetimeArray, or a non-duration string to a TimedeltaArray). The helper _validation_error_message builds the message; the allow_listlike=False variant tells the user only a scalar or NaT is accepted.

Solutions

  1. Pre-parse with pd.to_datetime(value, errors='coerce') and check for NaT.
  2. Pass a Timestamp/Timedelta object directly: Timestamp('2020-01-01') instead of a raw string.
  3. Use NaT (pandas.NaT) explicitly for missing values instead of None or ''.
  4. Validate format with pd.to_datetime(series, format='%Y-%m-%d') before assignment.

Example fix

# before
dti[0] = 'not-a-date'  # TypeError

# after
dti[0] = pd.Timestamp('2020-01-01')
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd
val = pd.to_datetime(value, errors='coerce')
if pd.isna(val) and not (value is pd.NaT or value == 'NaT'):
    raise ValueError(f'unparseable datetime scalar: {value!r}')
dti[0] = val

Type guard

import pandas as pd

def is_valid_datetime_scalar(v) -> bool:
    return isinstance(v, (pd.Timestamp, type(pd.NaT))) or (
        isinstance(v, str) and not pd.isna(pd.to_datetime(v, errors='coerce'))
    )

Try / catch

try:
    dti[0] = raw
except TypeError as e:
    if 'value should be' in str(e):
        dti[0] = pd.to_datetime(raw, errors='coerce')
    else:
        raise

Prevention

When it happens

Trigger: Setting a single datetime value on a DatetimeIndex with a string like 'not-a-date'. Filling a datetime column with fillna('garbage'). Assigning to a TimedeltaArray with 'abc'. Internal _validate_scalar calls from setitem/fillna where listlike input is disallowed.

Common situations: User feeds a free-text column into a datetime slot expecting pandas to coerce. Locale/format mismatch (e.g., '31/12/2020' vs '%m/%d/%Y'). Whitespace or invisible characters in strings. Copy-paste of partial timestamps.

Related errors


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

Appendix: source

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

            listlike inputs are allowed.
        unbox : bool, default True
            Whether to unbox the result before returning.  Note: unbox=False
            skips the setitem compatibility check.

        Returns
        -------
        self._scalar_type or NaT
        """
        if isinstance(value, self._scalar_type):
            pass

        elif isinstance(value, str):
            # NB: Careful about tzawareness
            try:
                value = self._scalar_from_string(value)
            except ValueError as err:
                msg = self._validation_error_message(value, allow_listlike)
                raise TypeError(msg) from err

        elif is_valid_na_for_dtype(value, self.dtype):
            # GH#18295
            value = NaT

        elif isna(value):
            # if we are dt64tz and value is dt64("NaT"), dont cast to NaT,
            #  or else we'll fail to raise in _unbox_scalar
            msg = self._validation_error_message(value, allow_listlike)
            raise TypeError(msg)

        elif isinstance(value, self._recognized_scalars):
            # error: Argument 1 to "Timestamp" has incompatible type "object"; expected
            # "integer[Any] | float | str | date | datetime | datetime64"
            value = self._scalar_type(value)  # type: ignore[arg-type]

        else:
            msg = self._validation_error_message(value, allow_listlike)

View on GitHub (pinned to 3b7651241d)