Textualize/textual · error · NoMatches
No nodes match {self!r} on dom{self.node!r}
Error message
No nodes match {self!r} on dom{self.node!r} What it means
last() raises NoMatches when the query returned an empty node list, mirroring first()'s empty check but for the last-matched node accessor. The message (with its quirky 'dom' wording) includes the query repr and node for diagnosis.
Source
Thrown at src/textual/css/query.py:323
def last(
self, expect_type: type[ExpectType] | None = None
) -> 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]:View on GitHub (pinned to 06dbeef4bb)
Solutions
- Confirm the target widget exists and is mounted under the queried node at call time
- Defer the query until after mount/compose (call_after_refresh)
- Catch NoMatches to handle 'not present yet' gracefully
Example fix
# before
row = self.query("DataTable .row--highlight").last() # NoMatches
# after
from textual.css.query import NoMatches
try:
row = self.query("DataTable .row--highlight").last()
except NoMatches:
row = None Defensive patterns
Strategy: try-catch
Validate before calling
q = screen.query(selector) node = q.nodes[-1] if q.nodes else None
Try / catch
from textual.css.query import NoMatches
try:
node = q.last()
except NoMatches:
node = None Prevention
- Check .nodes emptiness before first()/last() on optional widgets
When it happens
Trigger: `screen.query("DataTable").last()` with no DataTable mounted; selectors referencing widgets on other screens; querying after remove() of the only match.
Common situations: Same family as first()'s NoMatches: timing (not yet mounted), misspelled selectors, or querying the wrong node subtree.
Related errors
- No nodes match {self!r} on {self.node!r}
- No nodes match {query_selector!r} on {base_node!r}
- Node matching {query_selector!r} is the wrong type; expected
- Call to query_one resulted in more than one matched node
- Unable to parse filter {filter!r} as query
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/04dc855ed27485b5.
Report an issue: GitHub.