denoland/deno · error · Error
Empty selector
Error message
Empty selector
What it means
Thrown by popSelector() in cli/js/40_lint_selector.js when a nested selector list is popped but the enclosing (parent-level) selector it would attach to is empty — meaning some comma-separated segment or pseudo argument contains no actual selector text. It is the parser's guard against empty selector fragments.
Source
Thrown at cli/js/40_lint_selector.js:773
}
return result;
}
/**
* @param {Selector[]} result
* @param {Selector[]} stack
*/
function popSelector(result, stack) {
const sel = /** @type {Selector} */ (stack.pop());
if (stack.length === 0) {
result.push(sel);
stack.push([]);
} else {
const prev = /** @type {Selector} */ (stack.at(-1));
if (prev.length === 0) {
throw new Error(`Empty selector`);
}
const node = prev.at(-1);
if (node === undefined) {
throw new Error(`Empty node`);
}
if (node.type === PSEUDO_NTH_CHILD) {
node.of = sel;
} else if (
node.type === PSEUDO_HAS || node.type === PSEUDO_IS ||
node.type === PSEUDO_NOT
) {
node.selectors.push(sel);
} else {
throw new Error(`Multiple selectors not allowed here`);
}
}View on GitHub (pinned to 89f33cbef2)
Solutions
- Remove the empty segment: fill in ":has(...)", delete leading/double/trailing commas
- When building selectors dynamically, filter out empty parts before joining with ', '
Example fix
// before
const sel = parts.join(", "); // parts = ["Foo", "", "Bar"] → "Foo, , Bar"
// after
const sel = parts.filter((p) => p.length > 0).join(", "); Defensive patterns
Strategy: validation
Validate before calling
function noEmptySegments(sel) {
const inner = sel.slice(sel.indexOf("(") + 1, sel.lastIndexOf(")"));
if (/\(\s*\)|,\s*,|^\s*,|,\s*$/.test(sel)) {
throw new Error(`empty selector segment in '${sel}'`);
}
} Prevention
- When generating selectors from arrays, filter(Boolean) before join(", ")
- Never ship ":has()" / ":not()" with empty parens — fill them or drop them
When it happens
Trigger: Selectors with an empty segment: ":has()" (empty parens), "Foo > , Bar" or ", Foo" (empty comma segment), "Foo,, Bar". Any place where a selector was expected but nothing preceded the comma/closing brace.
Common situations: Programmatically joining selector parts where one part is an empty string; leftover double commas after deleting a selector from a list; writing ":not()" while sketching a rule and forgetting to fill it in.
Related errors
- Unknown attribute operator: '${s}'
- Expected token '${token}', but got '${this.token}'.\n\n${thi
- Invalid RegExp pattern: ${raw}
- Expected 'of' keyword in ':nth-child' but got: ${lex.value}
- Unknown pseudo selector: '${lex.value}'
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/ff24a58edd4bece7.
Report an issue: GitHub.