{"record":{"id":"c9739d18b14df58b","repo":"amruthpillai/reactive-resume","slug":"pseudo-elements-are-not-supported","errorCode":null,"errorMessage":"Pseudo-elements are not supported.","messagePattern":"Pseudo-elements are not supported\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/resume/src/stylesheet/selector.ts","lineNumber":231,"sourceCode":"\t\t\t\tconst nested = childrenOf(node);\n\t\t\t\tif (nested.length !== 1 || nested[0]?.type !== \"SelectorList\") {\n\t\t\t\t\tthrow new Error(`:${name} requires a selector list.`);\n\t\t\t\t}\n\t\t\t\tconst selectors = compileSelectorList(nested[0], { depth: context.depth + 1 });\n\t\t\t\treturn { type: \"pseudo\", name: name as \"is\" | \"where\" | \"not\", selectors };\n\t\t\t}\n\t\t\tif (name === \"nth-child\" || name === \"nth-of-type\") {\n\t\t\t\tif (context.depth >= SEMANTIC_CSS_LIMITS_V1.maxFunctionDepth) {\n\t\t\t\t\tthrow new Error(\"Selector function nesting is too deep.\");\n\t\t\t\t}\n\t\t\t\treturn compileNth(node, name, context);\n\t\t\t}\n\t\t\tthrow new Error(`Unsupported pseudo-class :${name}.`);\n\t\t}\n\t\tcase \"ClassSelector\":\n\t\t\tthrow new Error(\"Custom class selectors are not supported.\");\n\t\tcase \"PseudoElementSelector\":\n\t\t\tthrow new Error(\"Pseudo-elements are not supported.\");\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported selector node ${node.type}.`);\n\t}\n}\n\nfunction compileComplex(node: SelectorAst, context: CompileContext): CompiledComplexSelector {\n\tif (node.type !== \"Selector\") throw new Error(\"Expected a Selector AST.\");\n\n\tconst compounds: CompiledCompoundSelector[] = [];\n\tconst combinators: Combinator[] = [];\n\tlet selectors: CompiledSimpleSelector[] = [];\n\tfor (const child of childrenOf(node)) {\n\t\tif (child.type === \"Combinator\") {\n\t\t\tconst name = astName(child) as Combinator;\n\t\t\tif (![\" \", \">\", \"+\", \"~\"].includes(name) || selectors.length === 0) {\n\t\t\t\tthrow new Error(\"Unsupported or misplaced combinator.\");\n\t\t\t}\n\t\t\tvalidateCompound(selectors);","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/resume/src/stylesheet/selector.ts#L213-L249","documentation":"Thrown by compileSimple in the PseudoElementSelector branch. Pseudo-elements (::before, ::after, ::first-line, etc.) are not supported because the resume renderer works on a semantic node tree that has no generated pseudo-element boxes.","triggerScenarios":"Writing section::before, ::after, item::first-letter, or any pseudo-element.","commonSituations":"Porting decorative CSS that uses ::before/::after for icons or separators; habits from print-style CSS.","solutions":["Target a real semantic node instead (e.g. icon, list-marker, horizontal-rule).","Use a registered attribute or role to express the decoration target.","Move the decoration into the template structure rather than a pseudo-element."],"exampleFix":"// before\nsection::before\n// after\nicon[type~='bullet']","handlingStrategy":"validation","validationCode":"const hasPseudoElement = /::/.test(selector);\nconst isPseudoElementFree = (s) => !hasPseudoElement(s);\n// reject any '::' token before compiling","typeGuard":"const isRejected = (r) => r.selector === null && typeof r.error === 'string';","tryCatchPattern":"const result = compileSelector(selector);\nif (result.selector === null && result.error === 'Pseudo-elements are not supported.') {\n  targetRealSemanticNode(selector);\n}","preventionTips":["The semantic tree has no pseudo-element boxes; target real nodes instead (icon, list-marker, horizontal-rule).","Do not port ::before/::after decorations from web CSS.","Lint selectors for '::' tokens before saving."],"tags":["semantic-css","selector","pseudo-element","validation"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}