amruthpillai/reactive-resume · error · Error

:${name} requires a selector list.

Error message

:${name} requires a selector list.

What it means

Thrown by compileSimple for :is, :where, or :not when the pseudo-class's children are not exactly one SelectorList node. These functional pseudo-classes require a single comma-separated selector list as their argument.

Source

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

			if ((matcher === null || matcher === undefined) !== (value === null)) {
				throw new Error("Attribute selector matcher and value must be used together.");
			}
			return { type: "attribute", name, matcher: matcher ?? null, value };
		}
		case "PseudoClassSelector": {
			const name = astName(node);
			if (["root", "first-child", "last-child", "only-child"].includes(name)) {
				if (node.children !== null && node.children !== undefined)
					throw new Error(`:${name} does not accept arguments.`);
				return { type: "pseudo", name: name as "root" | "first-child" | "last-child" | "only-child" };
			}
			if (["is", "where", "not"].includes(name)) {
				if (context.depth >= SEMANTIC_CSS_LIMITS_V1.maxFunctionDepth) {
					throw new Error("Selector function nesting is too deep.");
				}
				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}.`);

View on GitHub (pinned to 3a5b12e2a4)

Solutions

  1. Author the selector as a string: :is(section, item) so css-tree builds the correct SelectorList.
  2. If building AST manually, wrap the argument list in a SelectorList node with the Selector children.
  3. Ensure at least one selector is present inside the function.

Example fix

// before
// AST: PseudoClassSelector{name:'is', children:[Selector, Selector]}
// after
:is(section, item)
Defensive patterns

Strategy: try-catch

Validate before calling

import { compileSelector } from '@reactive-resume/resume';

const isValid = (source) => compileSelector(source).selector !== null;
// for :is/:where/:not, prefer passing a string so css-tree wraps args in a SelectorList

Type guard

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

Try / catch

const result = compileSelector(astOrString);
if (result.selector === null && result.error.endsWith(' requires a selector list.')) {
  rewriteAsSelectorListArgument();
}

Prevention

When it happens

Trigger: A programmatically built AST whose children are not a single SelectorList; malformed :is() with empty or wrong-structured children; css-tree edge cases producing non-SelectorList children.

Common situations: Hand-constructing CssNode objects; transforming ASTs without preserving the SelectorList wrapper; partial parses.

Related errors


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