Textualize/textual · error · ReactiveError

Node is missing data; Check you are calling super().__init__

Error message

Node is missing data; Check you are calling super().__init__(...) in the {obj.__class__.__name__}() constructor, before setting reactives.

What it means

Reactive setter guard: attempting to set a reactive on an object whose DOMNode base was not initialized (missing '_id'). Same root cause as the getter variant but on assignment via __set__ or mutate_reactive.

Source

Thrown at src/textual/reactive.py:320

            )
        if not hasattr(obj, internal_name := self.internal_name):
            self._initialize_reactive(obj, self.name)

        if hasattr(obj, self.compute_name):
            value: ReactiveType
            old_value = getattr(obj, internal_name)
            value = getattr(obj, self.compute_name)()
            setattr(obj, internal_name, value)
            self._check_watchers(obj, self.name, old_value)
            return value
        else:
            return getattr(obj, internal_name)

    def _set(self, obj: Reactable, value: ReactiveType, always: bool = False) -> None:
        _rich_traceback_omit = True

        if not hasattr(obj, "_id"):
            raise ReactiveError(
                f"Node is missing data; Check you are calling super().__init__(...) in the {obj.__class__.__name__}() constructor, before setting reactives."
            )

        if isinstance(value, _Mutated):
            value = value.value
            always = True

        self._initialize_reactive(obj, self.name)

        if hasattr(obj, self.compute_name):
            raise AttributeError(
                f"Can't set {obj}.{self.name!r}; reactive attributes with a compute method are read-only"
            )

        name = self.name
        current_value = getattr(obj, name)
        # Check for private and public validate functions.
        private_validate_function = getattr(obj, f"_validate_{name}", None)

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Move reactive assignments to after super().__init__()
  2. Ensure super().__init__(...) is called unconditionally
  3. Initialize defaults via the reactive's default= or init= parameters instead of assignment in __init__

Example fix

# before
class MyWidget(Static):
    def __init__(self):
        self.count = 0  # reactive set before super
        super().__init__()
# after
class MyWidget(Static):
    count: reactive[int] = reactive(0)
    def __init__(self):
        super().__init__()
Defensive patterns

Strategy: validation

Validate before calling

if not hasattr(self, "_id"):
    raise RuntimeError("call super().__init__() before setting reactives")

Prevention

When it happens

Trigger: Assigning to a reactive attribute (obj.value = x) on an instance whose class __init__ never called super().__init__(), or setting reactives inside __init__ before the super call.

Common situations: Setting self.some_reactive = ... at the top of a custom widget's __init__ before super().__init__() runs.

Related errors


AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27). Data as JSON: /api/errors/788085e56d910931. Report an issue: GitHub.