reflex-dev/reflex · error · TypeError
Cannot use cached_property on a class without __set_name__.
Error message
Cannot use cached_property on a class without __set_name__.
What it means
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.
Source
Thrown at packages/reflex-base/src/reflex_base/vars/base.py:2068
)
raise TypeError(msg)
def __get__(self, instance: Any, owner: type | None = None):
"""Get the cached property.
Args:
instance: The instance to get the cached property from.
owner: The owner of the cached property.
Returns:
The cached property.
Raises:
TypeError: If the class does not have __set_name__.
"""
if self._attrname is None:
msg = "Cannot use cached_property on a class without __set_name__."
raise TypeError(msg)
cached_field_name = "_reflex_cache_" + self._attrname
try:
unique_id = object.__getattribute__(instance, cached_field_name)
except AttributeError:
unique_id = uuid.uuid4().int
object.__setattr__(instance, cached_field_name, unique_id)
if unique_id not in GLOBAL_CACHE:
GLOBAL_CACHE[unique_id] = self._func(instance)
return GLOBAL_CACHE[unique_id]
cached_property_no_lock = cached_property
class VarProtocol(Protocol):
"""A protocol for Var."""
__dataclass_fields__: ClassVar[dict[str, dataclasses.Field[Any]]]View on GitHub (pinned to 45b8ed5ab7)
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
Example fix
# before prop = _cached_property(fget) setattr(MyState, 'value', prop) # __set_name__ never runs MyState().value # TypeError # after prop = _cached_property(fget) setattr(MyState, 'value', prop) prop.__set_name__(MyState, 'value') # manually finish initialization
Defensive patterns
Strategy: validation
Validate before calling
def attach_prop(cls, prop, name: str):
setattr(cls, name, prop)
if getattr(prop, '_attrname', None) is None:
prop.__set_name__(cls, name) # ensure cached_property is initialized Type guard
def is_initialized_cached_property(prop) -> bool:
return getattr(prop, '_attrname', None) is not None Try / catch
try:
value = instance.some_prop
except TypeError as e:
if 'without __set_name__' in str(e):
type(instance).some_prop.__set_name__(type(instance), 'some_prop')
value = instance.some_prop
else:
raise Prevention
- Prefer class-body assignment over setattr for descriptors
- Always call __set_name__ manually after dynamic descriptor attachment
- Avoid monkeypatching cached_property descriptors in tests
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cannot assign the same cached_property to two different name
- The component `{comp_name}` only allows the components: {val
- Var-returning `@rx.memo` `{func_name}` cannot depend on embe
- Var-returning `@rx.memo` `{func_name}` cannot import `{lib}`
- `rx.Var[rx.Component]` parameters in `{fn_name}` must be nam
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/55fa405baa23d18d.
Report an issue: GitHub.