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 getting reactives.

What it means

Reactive getter guard: the object being read has no 'id' attribute, meaning the DOMNode superclass was never initialized. Reactive access requires the data structures that Widget/DOMNode.__init__ sets up.

Source

Thrown at src/textual/reactive.py:300

            obj_type: type[ReactableType],
        ) -> ReactiveType: ...

        @overload
        def __get__(
            self: Reactive[ReactiveType], obj: None, obj_type: type[ReactableType]
        ) -> Reactive[ReactiveType]: ...

    def __get__(
        self: Reactive[ReactiveType],
        obj: Reactable | None,
        obj_type: type[ReactableType],
    ) -> Reactive[ReactiveType] | ReactiveType:
        _rich_traceback_omit = True
        if obj is None:
            # obj is None means we are invoking the descriptor via the class, and not the instance
            return self
        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 getting reactives."
            )
        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

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Call super().__init__(...) at the start of the custom class's __init__
  2. If using @parameterized, ensure it forwards *args/**kwargs to the real constructor
  3. Avoid reading reactives before construction completes

Example fix

# before
class MyWidget(Static):
    def __init__(self):
        self.count = self.counter  # fails
# after
class MyWidget(Static):
    def __init__(self):
        super().__init__()
        self.count = self.counter
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(widget, Widget) and hasattr(widget, "id")

Prevention

When it happens

Trigger: A custom widget class fails to call super().__init__() (with @parameterized or in a manually managed __init__), then a reactive attribute is read on the instance.

Common situations: Custom widgets that define __init__ and forget the super call, or use of functools.partial/parameterized decorators that bypass initialization.

Related errors


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