{"record":{"id":"dc42326b4374dbbf","repo":"pandas-dev/pandas","slug":"you-cannot-add-any-new-attribute-key","errorCode":null,"errorMessage":"You cannot add any new attribute '{key}'","messagePattern":"You cannot add any new attribute '(.+?)'","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pandas/core/base.py","lineNumber":161,"sourceCode":"    def _freeze(self) -> None:\n        \"\"\"\n        Prevents setting additional attributes.\n        \"\"\"\n        object.__setattr__(self, \"__frozen\", True)\n\n    # prevent adding any attribute via s.xxx.new_attribute = ...\n    def __setattr__(self, key: str, value) -> None:\n        # _cache is used by a decorator\n        # We need to check both 1.) cls.__dict__ and 2.) getattr(self, key)\n        # because\n        # 1.) getattr is false for attributes that raise errors\n        # 2.) cls.__dict__ doesn't traverse into base classes\n        if getattr(self, \"__frozen\", False) and not (\n            key == \"_cache\"\n            or key in type(self).__dict__\n            or getattr(self, key, None) is not None\n        ):\n            raise AttributeError(f\"You cannot add any new attribute '{key}'\")\n        object.__setattr__(self, key, value)\n\n\nclass SelectionMixin(Generic[NDFrameT]):\n    \"\"\"\n    mixin implementing the selection & aggregation interface on a group-like\n    object sub-classes need to define: obj, exclusions\n    \"\"\"\n\n    obj: NDFrameT\n    _selection: IndexLabel | None = None\n    exclusions: frozenset[Hashable]\n    _internal_names = [\"_cache\", \"__setstate__\"]\n    _internal_names_set = set(_internal_names)\n\n    @final\n    @property\n    def _selection_list(self):","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/base.py#L143-L179","documentation":"Raised by FrozenObject.__setattr__ (via _freeze()) when you try to set a brand-new attribute on a pandas object that has been frozen. Frozen objects (some Index subclasses, etc.) only allow setting attributes already declared on the class or _cache. This guards internal immutability invariants.","triggerScenarios":"Calling `idx.foo = 1` on a frozen Index, or monkey-patching attributes onto instances returned from internal pandas APIs that have invoked _freeze().","commonSituations":"Attaching metadata to a pandas object; subclassing without overriding __setattr__; stale tutorials suggesting `df.some_attr = ...`.","solutions":["Store auxiliary data in a separate dict/Series keyed by the object, not as an attribute.","Subclass and declare the attribute at class level if you need it.","Use the .attrs dict (df.attrs['key'] = value) for user metadata."],"exampleFix":"// before\nidx.custom = 'meta'  # raises\n\n// after\nobj.attrs['custom'] = 'meta'","handlingStrategy":"try-catch","validationCode":"allowed = set(type(obj).__dict__) | {'_cache'}\nif key not in allowed and getattr(obj, key, None) is None:\n    raise AttributeError(f'cannot add attribute {key} to frozen object')","typeGuard":"def is_frozen(obj) -> bool:\n    return getattr(obj, '_FrozenObject__frozen', False) or getattr(obj, '__frozen', False)","tryCatchPattern":"try:\n    obj.new_attr = value\nexcept AttributeError as e:\n    if 'cannot add any new attribute' in str(e):\n        obj.attrs['new_attr'] = value\n    else:\n        raise","preventionTips":["Use the .attrs dict for user metadata.","Avoid attaching attributes to pandas objects.","Subclass and declare attributes at class level."],"tags":["attribute","frozen","attributeerror","immutability"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}