{"record":{"id":"a3e706e431068c70","repo":"pandas-dev/pandas","slug":"you-can-only-set-the-value-of-existing-options","errorCode":null,"errorMessage":"You can only set the value of existing options","messagePattern":"You can only set the value of existing options","errorType":"exception","errorClass":"OptionError","httpStatus":null,"severity":"error","filePath":"pandas/_config/config.py","lineNumber":428,"sourceCode":"    \"\"\"provide attribute-style access to a nested dict\"\"\"\n\n    d: dict[str, Any]\n\n    def __init__(self, d: dict[str, Any], prefix: str = \"\") -> None:\n        object.__setattr__(self, \"d\", d)\n        object.__setattr__(self, \"prefix\", prefix)\n\n    def __setattr__(self, key: str, val: Any) -> None:\n        prefix = object.__getattribute__(self, \"prefix\")\n        if prefix:\n            prefix += \".\"\n        prefix += key\n        # you can't set new keys\n        # can you can't overwrite subtrees\n        if key in self.d and not isinstance(self.d[key], dict):\n            set_option(prefix, val)\n        else:\n            raise OptionError(\"You can only set the value of existing options\")\n\n    def __getattr__(self, key: str) -> Any:\n        prefix = object.__getattribute__(self, \"prefix\")\n        if prefix:\n            prefix += \".\"\n        prefix += key\n        try:\n            v = object.__getattribute__(self, \"d\")[key]\n        except KeyError as err:\n            raise OptionError(\"No such option\") from err\n        if isinstance(v, dict):\n            return DictWrapper(v, prefix)\n        else:\n            return get_option(prefix)\n\n    def __dir__(self) -> list[str]:\n        return list(self.d.keys())\n","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/_config/config.py#L410-L446","documentation":"Raised by `DictWrapper.__setattr__` (the `pd.options.<...> = value` API) when assigning to an attribute that is not an existing leaf option. The wrapper only allows overwriting a registered leaf value; setting a brand-new attribute or writing into a subtree namespace is rejected. New options must be registered via `register_option`, not assigned.","triggerScenarios":"`pd.options.foo = 1`, `pd.options.display.new_setting = 5`, or any assignment to a path that is not a registered scalar option.","commonSituations":"Trying to create a custom option by attribute assignment (not supported); typo on an existing leaf; writing to an intermediate namespace node instead of a leaf.","solutions":["Assign only to an existing leaf, e.g. `pd.options.display.max_rows = 10`.","To create a new option use `pd.set_option(key, value)` after `pd.core.config_init` or call `pd._config.config.register_option(key, default)`.","Fix typos against `dir(pd.options)` / `pd.describe_option()`."],"exampleFix":"# before\npd.options.display.mycustom = 5   # OptionError\n\n# after\npd.options.display.max_rows = 10  # existing leaf\n# or register a new one:\nfrom pandas._config.config import register_option\nregister_option('display.mycustom', 5)","handlingStrategy":"validation","validationCode":"import pandas as pd\ndef set_via_options(path: str, value):\n    parts = path.split('.')\n    node = pd.options\n    for p in parts[:-1]:\n        node = getattr(node, p)\n    if not isinstance(getattr(node, parts[-1], None), dict) and parts[-1] in dir(node):\n        setattr(node, parts[-1], value)\n    else:\n        raise ValueError(f'{path} is not an existing leaf option')","typeGuard":"def is_settable_leaf(path: str) -> bool:\n    import pandas as pd\n    parts = path.split('.')\n    node = pd.options\n    for p in parts[:-1]:\n        node = getattr(node, p, None)\n        if node is None:\n            return False\n    return parts[-1] in dir(node) and not isinstance(getattr(node, parts[-1]), dict)","tryCatchPattern":"from pandas._config.config import OptionError\ntry:\n    setattr(pd.options.display, attr, value)\nexcept OptionError:\n    # use set_option() or register a new option instead\n    ...","preventionTips":["Treat `pd.options.<...> =` as write-only to known leaves; use `set_option` otherwise.","For new options, always go through `register_option`, never attribute assignment.","Validate attribute names against `dir(pd.options.<namespace>)` before assignment."],"tags":["config","options-attribute","api-misuse","option-error"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}