pandas-dev/pandas · error · ValueError

Value must have type

Error message

Value must have type '{_type}'

What it means

Raised by the validator returned from `is_type_factory(_type)` (the `inner` closure at pandas/_config/config.py:860). It performs a STRICT type check: `type(x) != _type` (exact type equality, not `isinstance`). It is attached to options whose validator is an `is_type_factory(...)` and runs whenever `set_option`/`option_context`/DictWrapper assignment applies a new value to such an option.

Solutions

  1. Pass a value whose exact type matches the registered `_type` (e.g. real `bool`, not truthy ints).
  2. Inspect the option's validator: `pd._config.config._get_registered_option(key).validator` to learn the required type.
  3. Convert explicitly: `bool(x)`, `int(x)`, `str(x)` before setting.

Example fix

# before
pd.set_option('display.unicode.east_asian_width', 1)   # validator is is_type_factory(bool)
# ValueError: Value must have type '<class 'bool'>'

# after
pd.set_option('display.unicode.east_asian_width', True)
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd
from pandas._config.config import _get_registered_option
def coerce_for_option(key: str, value):
    opt = _get_registered_option(key)
    validator = getattr(opt, 'validator', None) if opt else None
    # Best-effort: ask the validator; if it raises, coerce common cases
    if validator is not None:
        try:
            validator(value)
        except (ValueError, TypeError):
            # naive coercion hints for strict-type validators
            for caster in (bool, int, float, str):
                try:
                    validator(caster(value))
                    return caster(value)
                except (ValueError, TypeError):
                    continue
            raise
    return value
pd.set_option('display.unicode.east_asian_width', coerce_for_option('display.unicode.east_asian_width', 1))

Type guard

def matches_option_type(key: str, value) -> bool:
    import pandas._config.config as c
    opt = c._get_registered_option(key)
    if not opt or not opt.validator:
        return True
    try:
        opt.validator(value)
        return True
    except Exception:
        return False

Try / catch

try:
    pd.set_option(key, value)
except ValueError as e:
    if 'Value must have type' in str(e):
        # coerce to the exact required type and retry
        ...
    raise

Prevention

When it happens

Trigger: `set_option(key, value)` where `key`'s validator is `is_type_factory(bool)` and you pass an int/string; or passing a subclass where the exact type differs (because the check is not isinstance-based).

Common situations: Passing `1`/`0` instead of `True`/`False` for a bool option; passing a numpy scalar where a Python `int`/`bool` is required; passing a `str` where an `int` is required; assuming isinstance-style leniency when the validator is strict.

Related errors


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

Appendix: source

Thrown at pandas/_config/config.py:860


def is_type_factory(_type: type[Any]) -> Callable[[Any], None]:
    """

    Parameters
    ----------
    `_type` - a type to be compared against (e.g. type(x) == `_type`)

    Returns
    -------
    validator - a function of a single argument x , which raises
                ValueError if type(x) is not equal to `_type`

    """

    def inner(x: object) -> None:
        if type(x) != _type:
            raise ValueError(f"Value must have type '{_type}'")

    return inner


def is_instance_factory(_type: type | tuple[type, ...]) -> Callable[[Any], None]:
    """

    Parameters
    ----------
    `_type` - the type to be checked against

    Returns
    -------
    validator - a function of a single argument x , which raises
                ValueError if x is not an instance of `_type`

    """
    if isinstance(_type, tuple):

View on GitHub (pinned to 3b7651241d)