{"record":{"id":"2d826ad441d59efa","repo":"pandas-dev/pandas","slug":"option-key-is-a-prefix-of-an-already-registere","errorCode":null,"errorMessage":"Option '{key}' is a prefix of an already-registered option","messagePattern":"Option '(.+?)' is a prefix of an already-registered option","errorType":"exception","errorClass":"OptionError","httpStatus":null,"severity":"error","filePath":"pandas/_config/config.py","lineNumber":595,"sourceCode":"\n    cursor = _global_config\n    msg = \"Path prefix to option '{option}' is already an option\"\n\n    for i, p in enumerate(path[:-1]):\n        if not isinstance(cursor, dict):\n            raise OptionError(msg.format(option=\".\".join(path[:i])))\n        if p not in cursor:\n            cursor[p] = {}\n        cursor = cursor[p]\n\n    if not isinstance(cursor, dict):\n        raise OptionError(msg.format(option=\".\".join(path[:-1])))\n\n    # a namespace already lives here, i.e. `key` is a path prefix to one or\n    # more already-registered options; registering it would clobber them\n    # (GH#29242)\n    if isinstance(cursor.get(path[-1]), dict):\n        raise OptionError(f\"Option '{key}' is a prefix of an already-registered option\")\n\n    cursor[path[-1]] = defval  # initialize\n\n    # save the option metadata\n    _registered_options[key] = RegisteredOption(\n        key=key, defval=defval, doc=doc, validator=validator, cb=cb\n    )\n\n\ndef deprecate_option(\n    key: str,\n    category: type[Warning],\n    msg: str | None = None,\n    rkey: str | None = None,\n    removal_ver: str | None = None,\n) -> None:\n    \"\"\"\n    Mark option `key` as deprecated, if code attempts to access this option,","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/_config/config.py#L577-L613","documentation":"Raised by `register_option` (GH#29242) when the target slot already holds a dict — i.e. a namespace with already-registered child options already lives at `key`. Registering a scalar here would clobber those children, so it is rejected. This is the inverse of errors 15/16: here the new key would shadow existing children rather than nest under an existing leaf.","triggerScenarios":"First `register_option('a.b', 1)` and `register_option('a.c', 2)` (so `a` is a namespace dict), then `register_option('a', 3)` — registering `a` as a leaf would destroy `a.b` and `a.c`.","commonSituations":"Trying to promote a namespace to a leaf after children were registered; auto-generated keys that collapse a parent namespace.","solutions":["Do not register a key that is a prefix of existing options; choose a non-overlapping key.","If you intend to remove the children, deprecate them first, then register the leaf.","Namespace your own keys (e.g. `mylib.*`) so they cannot collide with built-in namespaces like `display`."],"exampleFix":"# before\nregister_option('a.b', 1)\nregister_option('a', 2)   # OptionError: 'a' is a prefix of an already-registered option\n\n# after\nregister_option('a_root', 2)   # does not shadow the 'a.*' namespace","handlingStrategy":"validation","validationCode":"from pandas._config.config import _global_config\ndef key_is_not_prefix_of_existing(key: str) -> bool:\n    parts = key.split('.')\n    cursor = _global_config\n    for p in parts[:-1]:\n        cursor = cursor.get(p, {})\n    return not isinstance(cursor.get(parts[-1]), dict)","typeGuard":"def key_shadows_namespace(key: str) -> bool:\n    import pandas._config.config as c\n    parts = key.split('.')\n    cursor = c._global_config\n    for p in parts[:-1]:\n        cursor = cursor.get(p, {})\n    return isinstance(cursor.get(parts[-1]), dict)","tryCatchPattern":"from pandas._config.config import OptionError\ntry:\n    register_option(key, default)\nexcept OptionError as e:\n    if 'prefix of an already-registered option' in str(e):\n        # key would clobber children; choose a different key and retry\n        ...\n    raise","preventionTips":["Never register a key that is a prefix of existing options.","Namespace your keys (`mylib.*`) so they cannot collide with `display.*` etc.","Deprecate child options before collapsing a namespace into a leaf."],"tags":["config","register-option","prefix-collision","hierarchy","gh29242"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}