pandas-dev/pandas · error · ValueError

{k} is not a valid identifier

Error message

{k} is not a valid identifier

What it means

Raised by register_option (config.py:572-574) as a ValueError when any path segment of the dotted key does not match the regex `^tokenize.Name$` (a Python identifier). Each component of the dotted key must be a legal identifier on its own.

Source

Thrown at pandas/_config/config.py:574

    import tokenize

    key = key.lower()

    if key in _registered_options:
        raise OptionError(f"Option '{key}' has already been registered")
    if key in _reserved_keys:
        raise OptionError(f"Option '{key}' is a reserved key")

    # the default value should be legal
    if validator:
        validator(defval)

    # walk the nested dict, creating dicts as needed along the path
    path = key.split(".")

    for k in path:
        if not re.match("^" + tokenize.Name + "$", k):
            raise ValueError(f"{k} is not a valid identifier")
        if keyword.iskeyword(k):
            raise ValueError(f"{k} is a python keyword")

    cursor = _global_config
    msg = "Path prefix to option '{option}' is already an option"

    for i, p in enumerate(path[:-1]):
        if not isinstance(cursor, dict):
            raise OptionError(msg.format(option=".".join(path[:i])))
        if p not in cursor:
            cursor[p] = {}
        cursor = cursor[p]

    if not isinstance(cursor, dict):
        raise OptionError(msg.format(option=".".join(path[:-1])))

    # a namespace already lives here, i.e. `key` is a path prefix to one or
    # more already-registered options; registering it would clobber them

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use only identifier-safe characters: letters, digits (not leading), underscores within each segment.
  2. Sanitize each segment with re.sub(r'\W', '_', seg) and ensure it does not start with a digit.
  3. Validate with `seg.isidentifier()` per segment before calling register_option.

Example fix

# before
cf.register_option('display.1col', 1)  # 1col is not a valid identifier

# after
cf.register_option('display.first_col', 1)
Defensive patterns

Strategy: validation

Validate before calling

import re, tokenize
def valid_segments(key: str) -> bool:
    return all(re.match('^' + tokenize.Name + '$', seg) for seg in key.lower().split('.'))

Type guard

def is_valid_option_key(key: str) -> bool:
    import re, tokenize
    return all(re.match('^' + tokenize.Name + '$', s) for s in key.split('.'))

Prevention

When it happens

Trigger: cf.register_option('display.1col', 1) — '1col' starts with a digit; or 'display.foo-bar' where 'foo-bar' contains a hyphen.

Common situations: Embedding user input or numeric values into an option key; using kebab-case instead of dot.snake_case.

Related errors


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