Textualize/textual · error · WrongType

Query value is the wrong type; expected type {expect_type.__

Error message

Query value is the wrong type; expected type {expect_type.__name__!r}, found {last}

What it means

last() applies the same expect_type isinstance check as first(), but against the final matched node; on mismatch it raises WrongType naming the expected class and the found node. Both errors can occur on one call — NoMatches if empty, WrongType if the last node's type differs.

Source

Thrown at src/textual/css/query.py:326

    ) -> QueryType | ExpectType:
        """Get the *last* matching node.

        Args:
            expect_type: Require matched node is of this type,
                or None for any type.

        Raises:
            WrongType: If the wrong type was found.
            NoMatches: If there are no matching nodes in the query.

        Returns:
            The matching Widget.
        """
        if not self.nodes:
            raise NoMatches(f"No nodes match {self!r} on dom{self.node!r}")
        last = self.nodes[-1]
        if expect_type is not None and not isinstance(last, expect_type):
            raise WrongType(
                f"Query value is the wrong type; expected type {expect_type.__name__!r}, found {last}"
            )
        return last

    if TYPE_CHECKING:

        @overload
        def results(self) -> Iterator[QueryType]: ...

        @overload
        def results(self, filter_type: type[ExpectType]) -> Iterator[ExpectType]: ...

    def results(
        self, filter_type: type[ExpectType] | None = None
    ) -> Iterator[QueryType | ExpectType]:
        """Get query results, optionally filtered by a given type.

        Args:

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Pass the correct/actual type, or a common base class (Widget/Static as appropriate)
  2. Narrow the selector to only the intended widget type (e.g. `"Static.content"`)
  3. Omit expect_type and isinstance-check the result when types legitimately vary

Example fix

# before
node = self.query(".footer-item").last(Static)  # WrongType (it's a Button)
# after
node = self.query(".footer-item").last(Button)
Defensive patterns

Strategy: type-guard

Validate before calling

q = screen.query(selector)
node = q.nodes[-1] if q.nodes and isinstance(q.nodes[-1], Static) else None

Type guard

def last_is_type(q, cls) -> bool:
    return bool(q.nodes) and isinstance(q.nodes[-1], cls)

Try / catch

from textual.css.query import WrongType
try:
    node = q.last(Static)
except WrongType:
    node = q.last()

Prevention

When it happens

Trigger: `self.query("Widget").last(Static)` where the last widget in the match list is an Input; mixing widget types under one selector then asserting a single type.

Common situations: Broad selectors that match heterogeneous widget types combined with a strict expect_type; DOM reordering making a different widget last.

Related errors


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