{"record":{"id":"8a7f1aaccd1ebba4","repo":"pandas-dev/pandas","slug":"option-key-has-already-been-registered","errorCode":null,"errorMessage":"Option '{key}' has already been registered","messagePattern":"Option '(.+?)' has already been registered","errorType":"exception","errorClass":"OptionError","httpStatus":null,"severity":"error","filePath":"pandas/_config/config.py","lineNumber":561,"sourceCode":"        Function of a single argument, should raise `ValueError` if\n        called with a value which is not a legal value for the option.\n    cb\n        a function of a single argument \"key\", which is called\n        immediately after an option value is set/reset. key is\n        the full name of the option.\n\n    Raises\n    ------\n    ValueError if `validator` is specified and `defval` is not a valid value.\n\n    \"\"\"\n    import keyword\n    import tokenize\n\n    key = key.lower()\n\n    if key in _registered_options:\n        raise OptionError(f\"Option '{key}' has already been registered\")\n    if key in _reserved_keys:\n        raise OptionError(f\"Option '{key}' is a reserved key\")\n\n    # the default value should be legal\n    if validator:\n        validator(defval)\n\n    # walk the nested dict, creating dicts as needed along the path\n    path = key.split(\".\")\n\n    for k in path:\n        if not re.match(\"^\" + tokenize.Name + \"$\", k):\n            raise ValueError(f\"{k} is not a valid identifier\")\n        if keyword.iskeyword(k):\n            raise ValueError(f\"{k} is a python keyword\")\n\n    cursor = _global_config\n    msg = \"Path prefix to option '{option}' is already an option\"","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/_config/config.py#L543-L579","documentation":"Raised by `register_option` when the lowercased `key` is already present in `_registered_options`. Keys are case-insensitive (lowercased before lookup), so re-registering under a different case still collides. pandas itself registers the built-in options during import, so common keys like `display.max_rows` are already taken.","triggerScenarios":"`register_option('display.max_rows', 10)` (pandas already registered it), or calling `register_option` twice with the same key.","commonSituations":"A third-party library trying to register a key pandas already owns; duplicate registration across modules; re-running a registration on notebook reload.","solutions":["Pick a unique, namespaced key (e.g. prefix with your package name: `mylib.feature.flag`).","Check existence first: `from pandas._config.config import _registered_options; key in _registered_options`.","Call `pd._config.config._registered_options[key].defval` and reuse rather than re-register if you just want the default."],"exampleFix":"# before\nfrom pandas._config.config import register_option\nregister_option('display.max_rows', 10)   # OptionError: already registered\n\n# after\nfrom pandas._config.config import register_option, _registered_options\nkey = 'mylib.something.enabled'\nif key not in _registered_options:\n    register_option(key, True)","handlingStrategy":"validation","validationCode":"from pandas._config.config import register_option, _registered_options\ndef safe_register(key: str, default, **kw):\n    key = key.lower()\n    if key in _registered_options:\n        return  # already registered; reuse\n    register_option(key, default, **kw)","typeGuard":"def is_registered(key: str) -> bool:\n    import pandas._config.config as c\n    return key.lower() in c._registered_options","tryCatchPattern":"from pandas._config.config import OptionError\ntry:\n    register_option(key, default)\nexcept OptionError:\n    # key already owned; reuse or pick a namespaced key\n    ...","preventionTips":["Namespace your keys (e.g. `mylib.*`) to avoid colliding with pandas' options.","Check `_registered_options` before registering, especially on module reload.","Register options once at import; guard with an idempotency flag."],"tags":["config","register-option","duplicate","namespace"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}