pandas-dev/pandas · error · TypeError

Invalid value '{value!s}' for dtype '{self.dtype}'

Error message

Invalid value '{value!s}' for dtype '{self.dtype}'

What it means

Raised by NumpyExtensionArray._validate_setitem_value when np_can_hold_element raises LossySetitemError — i.e., assigning a value that cannot be stored losslessly in the array's dtype (for example, a float 1.5 into an int64 array, or a large int into int8). It is the per-element validation gate for __setitem__/fillna-style writes on the backing ndarray.

Source

Thrown at pandas/core/arrays/numpy_.py:185

        if copy and result is scalars:
            result = result.copy()
        return cls(result)

    def _validate_setitem_value(self, value):
        if isinstance(value, type(self)):
            value = value._ndarray

        # Match Block._standardize_fill_value behavior
        if self._ndarray.dtype.kind != "O" and is_valid_na_for_dtype(
            value, self._ndarray.dtype
        ):
            value = self.dtype.na_value

        try:
            return np_can_hold_element(self._ndarray.dtype, value)
        except LossySetitemError as err:
            raise TypeError(
                f"Invalid value '{value!s}' for dtype '{self.dtype}'"
            ) from err
        except NotImplementedError:
            # np_can_hold_element doesn't handle all dtypes (e.g. "U"),
            # fall back to no validation for those.
            return value

    def searchsorted(
        self,
        value: NumpyValueArrayLike | ExtensionArray,
        side: Literal["left", "right"] = "left",
        sorter: NumpySorter | None = None,
    ) -> npt.NDArray[np.intp] | np.intp:
        # Parent's searchsorted calls _validate_setitem_value, which is
        # too strict for search (e.g. rejects float into int). Delegate
        # directly to numpy which handles cross-dtype searches correctly.
        return self._ndarray.searchsorted(value, side=side, sorter=sorter)  # type: ignore[arg-type]

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use a nullable/lossless dtype: convert the column to Float64/Int64/string/object before assigning.
  2. Pick a fill value compatible with the current dtype (e.g. 0 instead of 0.5 for int64).
  3. Cast the array via .astype(...) to a dtype that can hold the value before assignment.

Example fix

# before
s = pd.Series([1, 2, 3], dtype='int64')
s[s.isna()] = 1.5  # or s.iloc[0] = 1.5
# after
s = pd.Series([1, 2, 3], dtype='Int64')
s.iloc[0] = 1  # integer-compatible value
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
from pandas.core.dtypes.cast import np_can_hold_element
from pandas.errors import LossySetitemError

def can_hold(dtype, value) -> bool:
    try:
        np_can_hold_element(np.dtype(dtype), value)
        return True
    except (LossySetitemError, NotImplementedError):
        return False

Type guard

import numpy as np

def value_fits_dtype(value, dtype) -> bool:
    dt = np.dtype(dtype)
    try:
        np.array([value], dtype=dt)
        return True
    except (TypeError, ValueError, OverflowError):
        return False

Try / catch

try:
    arr[idx] = value
except TypeError:
    arr = arr.astype('Int64')
    arr[idx] = value

Prevention

When it happens

Trigger: Series/array __setitem__ on a NumpyExtensionArray-backed int column assigning a non-integer float; fillna with a value that does not fit the dtype; masked assignment where the rhs downcasts lossily.

Common situations: Filling NaN in an integer column with a float sentinel. Assigning NaN to a non-nullable integer dtype (use Int64 instead). Version upgrades where pandas tightened lossy-assignment validation.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/9f86da8cf1dce830. Report an issue: GitHub.