pandas-dev/pandas · error · ValueError

Must provide an even number of non-keyword arguments

Error message

Must provide an even number of non-keyword arguments

What it means

Raised by `set_option` when the positional arguments are not pairs. `set_option` accepts either `(key, value, key, value, ...)` or a single dict; after the dict is flattened, `nargs` must be nonzero and even. An odd or zero count triggers this ValueError before any option lookup happens.

Solutions

  1. Pass arguments as key/value pairs: `pd.set_option('display.max_rows', 10)`.
  2. For multiple options either pass them as alternating pairs or pass a single dict: `pd.set_option({'display.max_rows': 10, 'display.max_columns': 5})`.
  3. Double-check the count: number of positional args must be even and >= 2.

Example fix

# before
pd.set_option('display.max_rows')        # odd args -> ValueError

# after
pd.set_option('display.max_rows', 10)
# or
pd.set_option({'display.max_rows': 10, 'display.max_columns': 5})
Defensive patterns

Strategy: validation

Validate before calling

def safe_set_option(*args):
    if len(args) == 1 and isinstance(args[0], dict):
        args = tuple(kv for item in args[0].items() for kv in item)
    if len(args) % 2 != 0 or len(args) == 0:
        raise ValueError('set_option needs (key, value) pairs or a single dict')
    import pandas as pd
    pd.set_option(*args)
safe_set_option('display.max_rows', 10)

Type guard

null

Try / catch

try:
    pd.set_option(*opts)
except ValueError as e:
    if 'even number' in str(e):
        # rebuild opts as pairs/dict and retry
        ...
    raise

Prevention

When it happens

Trigger: `pd.set_option('display.max_rows')` (value missing), `pd.set_option('a', 1, 'b')` (unbalanced), or `pd.set_option()` with no args.

Common situations: Forgetting the value argument; miscounting when setting several options positionally; refactoring that drops one arg.

Related errors


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

Appendix: source

Thrown at pandas/_config/config.py:275

    Dictionary Input:

    >>> pd.set_option({"display.max_columns": 4, "display.precision": 1})
    >>> df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
    >>> df
    0  1  ...  3   4
    0  1  2  ...  4   5
    1  6  7  ...  9  10
    [2 rows x 5 columns]
    >>> pd.reset_option("display.max_columns")
    >>> pd.reset_option("display.precision")
    """
    # Handle dictionary input
    if len(args) == 1 and isinstance(args[0], dict):
        args = tuple(kv for item in args[0].items() for kv in item)

    nargs = len(args)
    if not nargs or nargs % 2 != 0:
        raise ValueError("Must provide an even number of non-keyword arguments")

    for k, v in zip(args[::2], args[1::2], strict=True):
        key = _get_single_key(k)

        opt = _get_registered_option(key)
        if opt and opt.validator:
            opt.validator(v)

        # walk the nested dict
        root, k_root = _get_root(key)
        root[k_root] = v

        if opt is not None and opt.cb:
            opt.cb(key)


def describe_option(pat: str = "", _print_desc: bool = True) -> str | None:
    """

View on GitHub (pinned to 3b7651241d)