Textualize/textual · error · InvalidQueryFormat

Unable to parse {query_selector!r} as a query; check for syn

Error message

Unable to parse {query_selector!r} as a query; check for syntax errors

What it means

query_one raises InvalidQueryFormat when the selector string cannot be tokenized/parsed by textual's CSS selector parser (TokenError from parse_selectors). This is a syntax error in the query, not a matching failure.

Source

Thrown at src/textual/dom.py:1510

            if cached_result is not None:
                return cached_result
            if (
                node := walk_breadth_search_id(
                    base_node, query_selector[1:], with_root=False
                )
            ) is not None:
                if expect_type is not None and not isinstance(node, expect_type):
                    raise WrongType(
                        f"Node matching {query_selector!r} is the wrong type; expected type {expect_type.__name__!r}, found {node}"
                    )
                base_node._query_one_cache[cache_key] = node
                return node
            raise NoMatches(f"No nodes match {query_selector!r} on {base_node!r}")

        try:
            selector_set = parse_selectors(query_selector)
        except TokenError:
            raise InvalidQueryFormat(
                f"Unable to parse {query_selector!r} as a query; check for syntax errors"
            ) from None

        if all(selectors.is_simple for selectors in selector_set):
            cache_key = (base_node._nodes._updates, query_selector, expect_type)
            cached_result = base_node._query_one_cache.get(cache_key)
            if cached_result is not None:
                return cached_result
        else:
            cache_key = None

        for node in walk_breadth_first(base_node, with_root=False):
            if not match(selector_set, node):
                continue
            if expect_type is not None and not isinstance(node, expect_type):
                raise WrongType(
                    f"Node matching {query_selector!r} is the wrong type; expected type {expect_type.__name__!r}, found {node}"
                )

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Fix the selector syntax — use simple supported forms like '#id', '.class', 'Type', 'Type#id'
  2. If constructing selectors dynamically, validate/strip components before joining
  3. For type queries, pass the class itself (query_one(Input)) instead of a hand-built string

Example fix

# before
self.query_one('Input#name extra:')  # unparseable

# after
self.query_one('Input#name')
Defensive patterns

Strategy: validation

Validate before calling

from textual.css.tokenize import parse_selectors
try:
    parse_selectors(selector)
except Exception:
    selector = sanitize(selector)  # or raise a clear config error
self.query_one(selector)

Type guard

def is_valid_selector(s: str) -> bool:
    try:
        parse_selectors(s)
        return True
    except Exception:
        return False

Try / catch

from textual.css.query import InvalidQueryFormat
try:
    w = self.query_one(selector)
except InvalidQueryFormat as e:
    raise ConfigError(f'bad selector {selector!r}') from e

Prevention

When it happens

Trigger: Passing a malformed selector to query_one: unbalanced brackets, stray characters, invalid combinators, or a type name that isn't a valid identifier.

Common situations: Building selectors dynamically from user input or f-strings that produce empty/invalid fragments; copying browser-CSS selectors with syntax textual doesn't support; string concatenation bugs leaving trailing characters.

Understand the failure class

Related errors


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