Textualize/textual · critical · RuntimeError
Widget is missing attributes; have you called the constructo
Error message
Widget is missing attributes; have you called the constructor in your widget class?
What it means
Raised while walking up the DOM looking for the enclosing Screen: an AttributeError occurred while following _parent links, meaning the widget's internal attributes were never initialized. This almost always means a custom widget's __init__ did not call super().__init__().
Source
Thrown at src/textual/dom.py:802
def screen(self) -> "Screen[object]":
"""The screen containing this node.
Returns:
A screen object.
Raises:
NoScreen: If this node isn't mounted (and has no screen).
"""
# Get the node by looking up a chain of parents
# Note that self.screen may not be the same as self.app.screen
from textual.screen import Screen
node: MessagePump | None = self
try:
while node is not None and not isinstance(node, Screen):
node = node._parent
except AttributeError:
raise RuntimeError(
"Widget is missing attributes; have you called the constructor in your widget class?"
) from None
if not isinstance(node, Screen):
raise NoScreen("node has no screen")
return node
@property
def id(self) -> str | None:
"""The ID of this node, or None if the node has no ID."""
return self._id
@id.setter
def id(self, new_id: str) -> str:
"""Sets the ID (may only be done once).
Args:
new_id: ID for this node.
View on GitHub (pinned to 06dbeef4bb)
Solutions
- Add super().__init__(*args, **kwargs) as the first statement of the custom widget's __init__
- Verify no intermediate base class in the hierarchy swallows the constructor call
- If constructing raw DOMNode/Widget instances in tests, use the normal constructor path instead of __new__-style hacks
Example fix
# before
class MyWidget(Widget):
def __init__(self, label):
self.label = label # forgot super().__init__()
# after
class MyWidget(Widget):
def __init__(self, label: str):
super().__init__()
self.label = label Defensive patterns
Strategy: validation
Validate before calling
# before touching screen-dependent APIs: assert hasattr(widget, '_parent'), 'super().__init__() not called?'
Type guard
def is_initialized(node) -> bool:
return hasattr(node, '_parent') and hasattr(node, '_nodes') Prevention
- Always call super().__init__() first in custom widget constructors
- Lint for __init__ without super() in widget subclasses
- Run app smoke tests that mount every custom widget
When it happens
Trigger: Defining a widget subclass whose __init__ forgets to call super().__init__() (or Widget.__init__), then accessing widget.screen (directly or via any API that needs the screen, e.g. styles, refresh, posting messages).
Common situations: Custom widget with a custom constructor that sets attributes before/without calling the parent constructor; overriding __new__ or partially initializing objects in tests; copy-pasted widget code that drops the super() call.
Related errors
- Node is missing data; Check you are calling super().__init__
- Node is missing data; Check you are calling super().__init__
- A widget can't be its own parent
- Widget positional arguments must be Widget subclasses; not {
- Can't animate attribute {attribute!r} on {obj!r}; attribute
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/b6f35d58b4668e7d.
Report an issue: GitHub.