pandas-dev/pandas · error · ValueError

Value must have type '{_type}'

Error message

Value must have type '{_type}'

What it means

Raised by the validator produced by is_type_factory (config.py:844-862) when type(value) != _type (strict type equality, not isinstance). Validators like is_int/is_bool/is_float/is_str use this factory, so a value of a derived/subclass type (e.g. np.int64 vs int, or a bool subclass) will fail. The validator is invoked on the default at register time and on every set_option value.

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 71959b8cb9)

Solutions

  1. Coerce before set_option: set_option('x', int(value)) or bool(value).
  2. Use is_instance_factory or a custom validator if numpy scalars must be accepted.
  3. Register the default with the exact Python type that matches the validator (e.g. plain int 5, not np.int64(5)).

Example fix

# before
import numpy as np
cf.register_option('myapp.count', np.int64(5), validator=cf.is_int)  # ValueError: type 'int' expected

# after
cf.register_option('myapp.count', int(5), validator=cf.is_int)
pd.set_option('myapp.count', int(some_np_scalar))
Defensive patterns

Strategy: type-guard

Validate before calling

def coerce_for_validator(value, validator_type):
    # is_type_factory uses type(x) == _type; coerce exact Python type
    if validator_type is int and not isinstance(value, int):
        return int(value)
    if validator_type is float and not isinstance(value, float):
        return float(value)
    if validator_type is bool and not isinstance(value, bool):
        return bool(value)
    return value

Type guard

def matches_strict_type(value, _type) -> bool:
    return type(value) is _type

Try / catch

try:
    pd.set_option(key, value)
except ValueError as e:
    if 'must have type' in str(e):
        pd.set_option(key, type(expected)(value))

Prevention

When it happens

Trigger: Registering an option with validator=is_int and default np.int64(5); or calling set_option on an int-validated option with True (bool, not int) or with a numpy integer.

Common situations: Passing numpy scalars (np.int64, np.float64) to an option validated with is_int/is_float — type(x) != int. Also passing True to an int-validated option, since type(True)==bool. Or a bool-validated option receiving 1/0.

Related errors


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