pandas-dev/pandas · error · ValueError
is not a valid identifier
Error message
{k} is not a valid identifier What it means
Raised by `register_option` when any dot-separated path component of the key fails the Python-identifier regex `^tokenize.Name$`. Path components must be valid identifiers so the key can be walked as nested attributes/DictWrapper nodes. The offending component `k` is named in the message.
Solutions
- Make every dot-separated segment a valid Python identifier (`[A-Za-z_][A-Za-z0-9_]*`).
- Replace dashes with underscores; prefix digit-led names with a letter/underscore.
- Split the key and validate each segment with `str.isidentifier()` before calling register_option.
Example fix
# before
register_option('my-lib.flag', True) # ValueError: not a valid identifier
# after
register_option('my_lib.flag', True) Defensive patterns
Strategy: validation
Validate before calling
import re, tokenize
def valid_identifier_path(key: str) -> bool:
return all(re.match('^' + tokenize.Name + '$', part) for part in key.split('.'))
if valid_identifier_path(new_key):
register_option(new_key, default) Type guard
def is_valid_option_path(key: str) -> bool:
import re, tokenize
return all(re.match('^' + tokenize.Name + '$', p) for p in key.split('.')) Try / catch
try:
register_option(key, default)
except ValueError as e:
if 'not a valid identifier' in str(e):
# sanitize segments (e.g. dash -> underscore) and retry
...
raise Prevention
- Restrict config keys to `[A-Za-z_][A-Za-z0-9_]*` segments separated by dots.
- Convert kebab-case external keys to snake_case before registering.
- Validate each segment with `str.isidentifier()` as a fast pre-check.
When it happens
Trigger: `register_option('a.1bad', ...)`, `register_option('my-lib.flag', ...)` (hyphen), `register_option('a..b', ...)` (empty segment), or any component with spaces/punctuation.
Common situations: Using config keys that mirror external identifiers containing dashes, digits-first, or punctuation; pasting keys from JSON/kebab-case config into pandas.
Related errors
- is a python keyword
- Option ' ' has already been registered
- Option ' ' is a prefix of an already-registered option
- Option ' ' is a reserved key
- Path prefix to option
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/078c91da19e5114d.
Report an issue: GitHub.
Appendix: 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 themView on GitHub (pinned to 3b7651241d)