Textualize/textual · error · TypeError

Widget positional arguments must be Widget subclasses; not {

Error message

Widget positional arguments must be Widget subclasses; not {child!r}

What it means

Widget's positional constructor arguments must all be Widget instances; anything else (a string, config dict, etc.) raises TypeError listing the offending value.

Source

Thrown at src/textual/widget.py:502

        self._tooltip: VisualType | None = None
        """The tooltip content."""
        self.absolute_offset: Offset | None = None
        """Force an absolute offset for the widget (used by tooltips)."""

        self._scrollbar_changes: set[tuple[bool, bool]] = set()
        """Used to stabilize scrollbars."""
        super().__init__(
            name=name,
            id=id,
            classes=self.DEFAULT_CLASSES if classes is None else classes,
        )

        if self in children:
            raise WidgetError("A widget can't be its own parent")

        for child in children:
            if not isinstance(child, Widget):
                raise TypeError(
                    f"Widget positional arguments must be Widget subclasses; not {child!r}"
                )
        self._pending_children = list(children)
        self.set_reactive(Widget.disabled, disabled)
        if self.BORDER_TITLE:
            self.border_title = self.BORDER_TITLE
        if self.BORDER_SUBTITLE:
            self.border_subtitle = self.BORDER_SUBTITLE

        self.lock = RLock()
        """`asyncio` lock to be used to synchronize the state of the widget.

        Two different tasks might call methods on a widget at the same time, which
        might result in a race condition.
        This can be fixed by adding `async with widget.lock:` around the method calls.
        """
        self._anchored: bool = False
        """Has this widget been anchored?"""

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Pass content via keyword: Static("label") or widget.update("label")
  2. Wrap non-widget values in an appropriate widget (Label, Static)
  3. Give children as Widget instances only

Example fix

# before
panel = Container("Settings")
# after
panel = Container(Label("Settings"))
Defensive patterns

Strategy: type-guard

Validate before calling

if not all(isinstance(c, Widget) for c in children):
    raise TypeError("positional args must be Widgets")

Type guard

def all_widgets(children: list) -> bool:
    return all(isinstance(c, Widget) for c in children)

Prevention

When it happens

Trigger: Widget("label") or Container({"id": "x"}) — passing strings/dicts positionally, which Widget reserves for child widgets.

Common situations: Confusing Widget(children=...) with Static-like content constructors; migrating code that assumed content positional args.

Related errors


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