Textualize/textual · error · TokenError

unknown pseudo-class {pseudo_class!r}; must be one of {frien

Error message

unknown pseudo-class {pseudo_class!r}; must be one of {friendly_list(VALID_PSEUDO_CLASSES)}

What it means

TokenError raised for an unknown pseudo-class with no close match — the message lists every valid pseudo-class via friendly_list(VALID_PSEUDO_CLASSES). Counterpart to the did-you-mean variant.

Source

Thrown at src/textual/css/tokenizer.py:333

            referenced_by=None,
        )

        if (
            token.name == "pseudo_class"
            and token.value.strip(":") not in VALID_PSEUDO_CLASSES
        ):
            pseudo_class = token.value.strip(":")
            suggestion = get_suggestion(pseudo_class, list(VALID_PSEUDO_CLASSES))
            all_valid = f"must be one of {friendly_list(VALID_PSEUDO_CLASSES)}"
            if suggestion:
                raise TokenError(
                    self.read_from,
                    self.code,
                    (line_no + 1, col_no + 1),
                    f"unknown pseudo-class {pseudo_class!r}; did you mean {suggestion!r}?; {all_valid}",
                )
            else:
                raise TokenError(
                    self.read_from,
                    self.code,
                    (line_no + 1, col_no + 1),
                    f"unknown pseudo-class {pseudo_class!r}; {all_valid}",
                )

        col_no += len(value)
        if col_no >= len(line):
            line_no += 1
            col_no = 0
        self.line_no = line_no
        self.col_no = col_no
        return token

    def skip_to(self, expect: Expect) -> Token:
        """Skip tokens.

        Args:

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Pick a valid pseudo-class from the list in the error message
  2. Use a different mechanism (variant, class, or component state) for unsupported structural pseudo-classes

Example fix

/* before */
Tab:nth-child(2) { color: red; }
/* after */
Tab.-active { color: red; }
Defensive patterns

Strategy: validation

Validate before calling

from textual.css.tokenizer import VALID_PSEUDO_CLASSES
def valid_pseudo(name: str) -> bool:
    return name.lstrip(':') in VALID_PSEUDO_CLASSES

Try / catch

from textual.css.tokenizer import TokenError
try:
    stylesheet.parse()
except TokenError as e:
    report(f"unsupported pseudo-class: {e}"); raise

Prevention

When it happens

Trigger: Using a pseudo-class that neither exists nor resembles a valid one, e.g. ':nth-child(2)', ':checked', or a typo like ':hvoer'.

Common situations: Porting web CSS selectors with structural pseudo-classes Textual doesn't support; custom pseudo-classes from other frameworks.

Related errors


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