{"record":{"id":"55fa405baa23d18d","repo":"reflex-dev/reflex","slug":"cannot-use-cached-property-on-a-class-without-se","errorCode":null,"errorMessage":"Cannot use cached_property on a class without __set_name__.","messagePattern":"Cannot use cached_property on a class without __set_name__\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/reflex-base/src/reflex_base/vars/base.py","lineNumber":2068,"sourceCode":"            )\n            raise TypeError(msg)\n\n    def __get__(self, instance: Any, owner: type | None = None):\n        \"\"\"Get the cached property.\n\n        Args:\n            instance: The instance to get the cached property from.\n            owner: The owner of the cached property.\n\n        Returns:\n            The cached property.\n\n        Raises:\n            TypeError: If the class does not have __set_name__.\n        \"\"\"\n        if self._attrname is None:\n            msg = \"Cannot use cached_property on a class without __set_name__.\"\n            raise TypeError(msg)\n        cached_field_name = \"_reflex_cache_\" + self._attrname\n        try:\n            unique_id = object.__getattribute__(instance, cached_field_name)\n        except AttributeError:\n            unique_id = uuid.uuid4().int\n            object.__setattr__(instance, cached_field_name, unique_id)\n        if unique_id not in GLOBAL_CACHE:\n            GLOBAL_CACHE[unique_id] = self._func(instance)\n        return GLOBAL_CACHE[unique_id]\n\n\ncached_property_no_lock = cached_property\n\n\nclass VarProtocol(Protocol):\n    \"\"\"A protocol for Var.\"\"\"\n\n    __dataclass_fields__: ClassVar[dict[str, dataclasses.Field[Any]]]","sourceCodeStart":2050,"sourceCodeEnd":2086,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-base/src/reflex_base/vars/base.py#L2050-L2086","documentation":"A cached_property only knows which instance attribute to cache into after __set_name__ runs at class-definition time. Accessing the property on an instance before __set_name__ was called (or when the descriptor was never assigned inside a class body) leaves _attrname None and this Reflex copy of functools.cached_property raises TypeError. Reflex uses this mechanism for caching ComputedVar values on State instances.","triggerScenarios":"Calling the property on an instance after manually attaching the descriptor via setattr(SomeClass, 'name', prop) (setattr does not invoke __set_name__), or invoking __get__ directly before the class body finished; uncommon in normal Reflex usage but reachable through dynamic State class construction.","commonSituations":"Dynamically building State classes at runtime with type() or setattr and attaching Reflex cached_property/ComputedVar descriptors; monkeypatching state attributes in tests; mixing manual descriptor wiring with Reflex's State machinery.","solutions":["Assign the descriptor inside a class body (or call prop.__set_name__(cls, 'attr_name') manually after dynamic assignment)","Use a plain property or a normal instance cache field instead of cached_property for dynamically attached attributes","Prefer defining ComputedVars declaratively in the State class rather than attaching them programmatically"],"exampleFix":"# before\nprop = _cached_property(fget)\nsetattr(MyState, 'value', prop)  # __set_name__ never runs\nMyState().value  # TypeError\n\n# after\nprop = _cached_property(fget)\nsetattr(MyState, 'value', prop)\nprop.__set_name__(MyState, 'value')  # manually finish initialization","handlingStrategy":"validation","validationCode":"def attach_prop(cls, prop, name: str):\n    setattr(cls, name, prop)\n    if getattr(prop, '_attrname', None) is None:\n        prop.__set_name__(cls, name)  # ensure cached_property is initialized","typeGuard":"def is_initialized_cached_property(prop) -> bool:\n    return getattr(prop, '_attrname', None) is not None","tryCatchPattern":"try:\n    value = instance.some_prop\nexcept TypeError as e:\n    if 'without __set_name__' in str(e):\n        type(instance).some_prop.__set_name__(type(instance), 'some_prop')\n        value = instance.some_prop\n    else:\n        raise","preventionTips":["Prefer class-body assignment over setattr for descriptors","Always call __set_name__ manually after dynamic descriptor attachment","Avoid monkeypatching cached_property descriptors in tests"],"tags":["reflex","cached-property","descriptor","dynamic-class-creation","typeerror"],"backgroundTag":"descriptor-reuse-in-class","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}