pandas-dev/pandas · error · TypeError

ExtensionArray.fillna does not support filling with a dict.

Error message

ExtensionArray.fillna does not support filling with a dict. Use Series.fillna instead.

What it means

Raised by SparseArray.fillna when `value` is a dict. The base ExtensionArray.fillna accepts dicts (position->value), but SparseArray only supports a scalar fill because each NA in sp_values maps to the same stored fill value. The message points users to Series.fillna for dict semantics.

Source

Thrown at pandas/core/arrays/sparse/array.py:858

        Returns
        -------
        SparseArray

        Notes
        -----
        When `value` is specified, the result's ``fill_value`` depends on
        ``self.fill_value``. The goal is to maintain low-memory use.

        If ``self.fill_value`` is NA, the result dtype will be
        ``SparseDtype(self.dtype, fill_value=value)``. This will preserve
        amount of memory used before and after filling.

        When ``self.fill_value`` is not NA, the result dtype will be
        ``self.dtype``. Again, this preserves the amount of memory used.
        """
        if isinstance(value, dict):
            raise TypeError(
                "ExtensionArray.fillna does not support filling with a dict. "
                "Use Series.fillna instead."
            )
        if limit is not None:
            raise ValueError("limit must be None")
        new_values = np.where(isna(self.sp_values), value, self.sp_values)

        if self._null_fill_value:
            # This is essentially just updating the dtype.
            new_dtype = SparseDtype(self.dtype.subtype, fill_value=value)
        else:
            new_dtype = self.dtype

        return self._simple_new(new_values, self._sparse_index, new_dtype)

    def shift(self, periods: int = 1, fill_value=None) -> Self:
        if not len(self) or periods == 0:
            return self.copy()

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use Series.fillna with a dict: pd.Series(sparse_arr).fillna({0:5, 2:7}).
  2. If only a single value is needed, pass a scalar: sparse_arr.fillna(0).
  3. For positional fills, rebuild from dense np.where logic.

Example fix

// before
arr.fillna({0: 5, 2: 7})
// after
pd.Series(arr).fillna({0: 5, 2: 7}).array
Defensive patterns

Strategy: fallback

Validate before calling

import pandas as pd

def fillna_sparse(arr, value):
    if isinstance(value, dict):
        return pd.Series(arr).fillna(value).array
    return arr.fillna(value)

Type guard

def is_scalar_fill(value) -> bool:
    from pandas.api.types import is_scalar
    return is_scalar(value)

Try / catch

try:
    return arr.fillna(value)
except TypeError as e:
    if 'dict' in str(e):
        return pd.Series(arr).fillna(value).array
    raise

Prevention

When it happens

Trigger: sparse_arr.fillna({0: 5, 2: 7}); passing a dict of position-keyed fills to the underlying .array via Series.fillna internals that forward the dict to the EA.

Common situations: Reusing a dict fillna pattern from dense Series code on the .array directly; generic fillna wrappers that pass dicts through.

Related errors


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