amruthpillai/reactive-resume · error · Error
Selector list has an unsupported number of selectors.
Error message
Selector list has an unsupported number of selectors.
What it means
Thrown by compileSelectorList when the number of comma-separated complex selectors in a single selector list is zero or exceeds SEMANTIC_CSS_LIMITS_V1.maxSelectorsPerRule (64). The lower bound (zero) guards against malformed/empty input; the upper bound caps the combinatorial matching cost since each selector in the list is independently compiled and matched against every node. This limit applies per rule, not per stylesheet.
Source
Thrown at packages/resume/src/stylesheet/selector.ts:274
continue;
}
const selector = compileSimple(child, context);
if (selector) selectors.push(selector);
}
if (selectors.length === 0 && compounds.length > 0) throw new Error("Selector cannot end with a combinator.");
validateCompound(selectors);
compounds.push({ selectors });
const specificity = SpecificityCalculator.calculateForAST(node).toArray();
return { compounds, combinators, specificity: [specificity[0], specificity[1], specificity[2]] };
}
function compileSelectorList(node: SelectorAst, context: CompileContext): readonly CompiledComplexSelector[] {
if (node.type !== "SelectorList") throw new Error("Expected a SelectorList AST.");
const selectors = childrenOf(node);
if (selectors.length === 0 || selectors.length > SEMANTIC_CSS_LIMITS_V1.maxSelectorsPerRule) {
throw new Error("Selector list has an unsupported number of selectors.");
}
return selectors.map((selector) => compileComplex(selector, context));
}
export function compileSelector(source: string | CssNode): CompileSelectorResult {
try {
const text = typeof source === "string" ? source : csstree.generate(source);
if (Array.from(text).length > SEMANTIC_CSS_LIMITS_V1.maxSelectorCodePoints)
throw new Error("Selector is too long.");
const ast = (
typeof source === "string" ? csstree.parse(source, { context: "selectorList", positions: true }) : source
) as SelectorAst;
return { selector: { selectors: compileSelectorList(ast, { depth: 0 }) } };
} catch (error) {
return { selector: null, error: error instanceof Error ? error.message : "Invalid selector." };
}
}
View on GitHub (pinned to 3a5b12e2a4)
Solutions
- If the error is from an empty source, ensure the selector string is non-empty and valid before calling compileSelector.
- If over the limit, split the single oversized selector list into multiple rules each with <= 64 selectors, or refactor to use :is() to group related targets into fewer list entries.
- Prefer semantic attribute/role selectors over long enumerations of element types — one 'item[role="list-item"]' replaces dozens of enumerated selectors.
- Validate the selector count before compilation if generating programmatically, and chunk the output.
Example fix
// before: 65+ comma-separated selectors
const source = 'a, b, c, /* ...65 total... */';
const { error } = compileSelector(source);
// error === 'Selector list has an unsupported number of selectors.'
// after: use :is() to group, or split into multiple rules
const source = ':is(a, b, c)';
const { selector, error } = compileSelector(source); Defensive patterns
Strategy: validation
Validate before calling
const MAX_SELECTORS = 64; // SEMANTIC_CSS_LIMITS_V1.maxSelectorsPerRule
function countSelectorList(source: string): number {
return source.split(',').length;
}
if (countSelectorList(source) === 0 || countSelectorList(source) > MAX_SELECTORS) {
// chunk or reject
} Type guard
function selectorListSizeOk(source: string): boolean {
const n = countSelectorList(source);
return n > 0 && n <= 64;
} Try / catch
const { selector, error } = compileSelector(source);
if (!selector && /unsupported number of selectors/.test(error)) {
// split the rule into chunks of <= 64 selectors
} Prevention
- Avoid enumerating many element types; use role/attribute selectors instead.
- Chunk generated comma lists to stay under 64 per rule.
- Reject empty selector input before compilation.
When it happens
Trigger: Passing an empty selector list to compileSelector (css-tree parses an empty string into a SelectorList with zero children). Authoring a rule with more than 64 comma-separated selectors like 'a, b, c, ..., <65th>'. Programmatic generation that expands a template into a huge comma-separated list without chunking.
Common situations: Auto-generated stylesheets that enumerate many node kinds in one rule instead of using semantic attributes/roles. Accidental empty-string compilation when a dynamic selector source is uninitialized. Bulk import of external CSS that was written for a full browser engine rather than the restricted semantic subset.
Related errors
- Selector has too many combinators.
- Selector is too long.
- Selector cannot end with a combinator.
- Selector name is missing.
- Attribute value is missing.
AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12).
Data as JSON: /api/errors/376e420886021dff.
Report an issue: GitHub.