Textualize/textual · error · WrongType

Child with id={id!r} is the wrong type; expected type {expec

Error message

Child with id={id!r} is the wrong type; expected type {expect_type.__name__!r}, found {child}

What it means

get_child_by_id found a child with the requested id, but its type does not match the expect_type argument, so WrongType is raised instead of returning a mistyped widget.

Source

Thrown at src/textual/widget.py:1113

        Args:
            id: The ID of the child.
            expect_type: Require the object be of the supplied type, or None for any type.

        Returns:
            The first child of this node with the ID.

        Raises:
            NoMatches: if no children could be found for this ID
            WrongType: if the wrong type was found.
        """
        child = self._get_dom_base()._nodes._get_by_id(id)
        if child is None:
            raise NoMatches(f"No child found with id={id!r}")
        if expect_type is None:
            return child
        if not isinstance(child, expect_type):
            raise WrongType(
                f"Child with id={id!r} is the wrong type; expected type {expect_type.__name__!r}, found {child}"
            )
        return child

    if TYPE_CHECKING:

        @overload
        def get_widget_by_id(self, id: str) -> Widget: ...

        @overload
        def get_widget_by_id(
            self, id: str, expect_type: type[ExpectType]
        ) -> ExpectType: ...

    def get_widget_by_id(
        self, id: str, expect_type: type[ExpectType] | None = None
    ) -> ExpectType | Widget:
        """Return the first descendant widget with the given ID.

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Correct expect_type to match the actual widget (or a base class of it)
  2. Change the widget in compose() to the expected type
  3. Drop expect_type and isinstance-check the result if flexible

Example fix

# before
item = self.get_child_by_id("list", expect_type=OptionList)
# after
item = self.get_child_by_id("list", expect_type=OptionList)
# or fix compose():
# OptionList(id="list") instead of ListView(id="list")
Defensive patterns

Strategy: type-guard

Validate before calling

child = self._get_dom_base()._nodes._get_by_id(id)
if child is not None and not isinstance(child, expect_type):
    # fix compose() or adjust expect_type

Type guard

def child_matches(child: object, expect_type: type) -> bool:
    return isinstance(child, expect_type)

Try / catch

try:
    w = self.get_child_by_id("x", expect_type=T)
except NoMatches:
    ...
except WrongType as e:
    w = self.query_one("#x")  # inspect actual type and adjust

Prevention

When it happens

Trigger: get_child_by_id("list", expect_type=ListView) when the child with id 'list' is actually a ListView subclass or a different widget type entirely.

Common situations: Refactoring markup that changed widget types while lookup code kept the old expect_type; subclass instances when an exact type was assumed.

Related errors


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