amruthpillai/reactive-resume · error · Error

Selector is too long.

Error message

Selector is too long.

What it means

Thrown by compileSelector before parsing, when the selector source text exceeds SEMANTIC_CSS_LIMITS_V1.maxSelectorCodePoints (2048 Unicode code points, measured via Array.from(text).length to count astral-plane characters correctly). This is a length guard to bound parsing and storage cost for the restricted semantic engine. Note this is per-selector-list, not per-rule, and is checked on the string (or css-tree-regenerated text) before csstree.parse runs.

Source

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

	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." };
	}
}

export function getSpecificity(_source: string): Specificity | null {
	return compileSelector(_source).selector?.selectors[0]?.specificity ?? null;
}

function buildTree(root: SemanticNode): Map<string, TreeNode> {
	const nodes = new Map<string, TreeNode>();
	const rootNode: TreeNode = { node: root, parent: null, children: [] };
	const stack = [{ source: root, target: rootNode }];
	nodes.set(root.key, rootNode);

View on GitHub (pinned to 3a5b12e2a4)

Solutions

  1. Shorten the selector to <= 2048 code points; move large data out of selector attribute values and into the semantic node attributes themselves where matching is direct.
  2. If a CssNode input is too long when regenerated, refactor the AST to be smaller before passing it in.
  3. Check the length with Array.from(selectorText).length at authoring/generation time and split or simplify before calling compileSelector.

Example fix

// before: attribute value bloats the selector past 2048 code points
const source = `item[data-url="${veryLongString}"]`;
const { error } = compileSelector(source);
// error === 'Selector is too long.'

// after: store the value on the node and select by a stable key/role
const source = 'item[role="link"]';
Defensive patterns

Strategy: validation

Validate before calling

const MAX_CP = 2048; // SEMANTIC_CSS_LIMITS_V1.maxSelectorCodePoints
const codePoints = Array.from(source).length;
if (codePoints > MAX_CP) {
  // shorten or reject before compileSelector
}

Type guard

function selectorLengthOk(source: string): boolean {
  return Array.from(source).length <= 2048;
}

Try / catch

const { selector, error } = compileSelector(source);
if (!selector && error === 'Selector is too long.') {
  // truncate/simplify and retry
}

Prevention

When it happens

Trigger: Passing a selector string longer than 2048 code points to compileSelector. Passing a CssNode whose regenerated text (csstree.generate) exceeds 2048 code points. Machine-generated selectors with extremely long attribute value lists or deeply nested :is() content whose textual form balloons past the limit.

Common situations: Embedding large data values in attribute selectors (e.g. matching against a long URL or blob). Auto-generated selectors that inline many alternatives. A dynamically assembled selector that accidentally includes a large payload (base64, JSON) as an attribute value.

Related errors


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