{"record":{"id":"85700f8305e94f65","repo":"Textualize/textual","slug":"unknown-pseudo-class-pseudo-class-r-did-you-mea","errorCode":null,"errorMessage":"unknown pseudo-class {pseudo_class!r}; did you mean {suggestion!r}?; must be one of {friendly_list(VALID_PSEUDO_CLASSES)}","messagePattern":"unknown pseudo-class (.+?); did you mean (.+?)\\?; must be one of (.+?)","errorType":"exception","errorClass":"TokenError","httpStatus":null,"severity":"error","filePath":"src/textual/css/tokenizer.py","lineNumber":326,"sourceCode":"\n        token = Token(\n            name,\n            value,\n            self.read_from,\n            self.code,\n            (line_no, col_no),\n            referenced_by=None,\n        )\n\n        if (\n            token.name == \"pseudo_class\"\n            and token.value.strip(\":\") not in VALID_PSEUDO_CLASSES\n        ):\n            pseudo_class = token.value.strip(\":\")\n            suggestion = get_suggestion(pseudo_class, list(VALID_PSEUDO_CLASSES))\n            all_valid = f\"must be one of {friendly_list(VALID_PSEUDO_CLASSES)}\"\n            if suggestion:\n                raise TokenError(\n                    self.read_from,\n                    self.code,\n                    (line_no + 1, col_no + 1),\n                    f\"unknown pseudo-class {pseudo_class!r}; did you mean {suggestion!r}?; {all_valid}\",\n                )\n            else:\n                raise TokenError(\n                    self.read_from,\n                    self.code,\n                    (line_no + 1, col_no + 1),\n                    f\"unknown pseudo-class {pseudo_class!r}; {all_valid}\",\n                )\n\n        col_no += len(value)\n        if col_no >= len(line):\n            line_no += 1\n            col_no = 0\n        self.line_no = line_no","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/css/tokenizer.py#L308-L344","documentation":"TokenError variant raised when a selector uses a pseudo-class Textual doesn't know, but a close match exists in VALID_PSEUDO_CLASSES — the message offers a did-you-mean suggestion (powered by get_suggestion).","triggerScenarios":"Writing selectors like '$button:hovered' (correct is ':hover'), ':focus' (correct ':focusable'/':blur' naming differs from web), ':disabled' etc. — any pseudo-class not in VALID_PSEUDO_CLASSES with a near match.","commonSituations":"Developers coming from web CSS who assume Textual supports the same pseudo-classes (:hover, :focus, :active) — Textual's names often differ.","solutions":["Apply the did-you-mean suggestion in the message","Check the VALID_PSEUDO_CLASSES list in textual/css/tokenizer.py or the docs for supported pseudo-classes","Replace web-CSS pseudo-classes with Textual equivalents (:hover -> :hover, :focus -> :focus, verify spelling)"],"exampleFix":"/* before */\nButton:pressed { background: blue; }\n/* after */\nButton:active { background: blue; }","handlingStrategy":"try-catch","validationCode":"from textual.css.tokenizer import VALID_PSEUDO_CLASSES\nimport re\n_PSEUDO = re.compile(r'::?[a-zA-Z-]+')\ndef pseudoclasses_valid(selector: str) -> bool:\n    return all(p.strip(':') in VALID_PSEUDO_CLASSES for p in _PSEUDO.findall(selector))","typeGuard":null,"tryCatchPattern":"from textual.css.tokenizer import TokenError\ntry:\n    stylesheet.parse()\nexcept TokenError as e:\n    if 'unknown pseudo-class' in str(e):\n        apply_suggestion(str(e))  # parse the did-you-mean suggestion","preventionTips":["Use Textual's pseudo-class names, not web CSS ones","Apply the did-you-mean suggestion directly","Validate selectors against VALID_PSEUDO_CLASSES in tests"],"tags":["textual","css","pseudo-class","selector","did-you-mean"],"backgroundTag":"unknown-css-pseudo-class","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}