amruthpillai/reactive-resume · error · Error

Pseudo-elements are not supported.

Error message

Pseudo-elements are not supported.

What it means

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.

Source

Thrown at packages/resume/src/stylesheet/selector.ts:231

				const nested = childrenOf(node);
				if (nested.length !== 1 || nested[0]?.type !== "SelectorList") {
					throw new Error(`:${name} requires a selector list.`);
				}
				const selectors = compileSelectorList(nested[0], { depth: context.depth + 1 });
				return { type: "pseudo", name: name as "is" | "where" | "not", selectors };
			}
			if (name === "nth-child" || name === "nth-of-type") {
				if (context.depth >= SEMANTIC_CSS_LIMITS_V1.maxFunctionDepth) {
					throw new Error("Selector function nesting is too deep.");
				}
				return compileNth(node, name, context);
			}
			throw new Error(`Unsupported pseudo-class :${name}.`);
		}
		case "ClassSelector":
			throw new Error("Custom class selectors are not supported.");
		case "PseudoElementSelector":
			throw new Error("Pseudo-elements are not supported.");
		default:
			throw new Error(`Unsupported selector node ${node.type}.`);
	}
}

function compileComplex(node: SelectorAst, context: CompileContext): CompiledComplexSelector {
	if (node.type !== "Selector") throw new Error("Expected a Selector AST.");

	const compounds: CompiledCompoundSelector[] = [];
	const combinators: Combinator[] = [];
	let selectors: CompiledSimpleSelector[] = [];
	for (const child of childrenOf(node)) {
		if (child.type === "Combinator") {
			const name = astName(child) as Combinator;
			if (![" ", ">", "+", "~"].includes(name) || selectors.length === 0) {
				throw new Error("Unsupported or misplaced combinator.");
			}
			validateCompound(selectors);

View on GitHub (pinned to 3a5b12e2a4)

Solutions

  1. Target a real semantic node instead (e.g. icon, list-marker, horizontal-rule).
  2. Use a registered attribute or role to express the decoration target.
  3. Move the decoration into the template structure rather than a pseudo-element.

Example fix

// before
section::before
// after
icon[type~='bullet']
Defensive patterns

Strategy: validation

Validate before calling

const hasPseudoElement = /::/.test(selector);
const isPseudoElementFree = (s) => !hasPseudoElement(s);
// reject any '::' token before compiling

Type guard

const isRejected = (r) => r.selector === null && typeof r.error === 'string';

Try / catch

const result = compileSelector(selector);
if (result.selector === null && result.error === 'Pseudo-elements are not supported.') {
  targetRealSemanticNode(selector);
}

Prevention

When it happens

Trigger: Writing section::before, ::after, item::first-letter, or any pseudo-element.

Common situations: Porting decorative CSS that uses ::before/::after for icons or separators; habits from print-style CSS.

Related errors


AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12). Data as JSON: /api/errors/c9739d18b14df58b. Report an issue: GitHub.