denoland/deno · error · Error
Expected 'of' keyword in ':nth-child' but got
Error message
Expected 'of' keyword in ':nth-child' but got: ${lex.value} What it means
The selector engine implements the CSS-style 'An+B of S' form: :nth-child(<step>[+/-offset] of <selector>). After reading the step/offset, the only keyword it accepts inside the parentheses is `of` (cli/js/40_lint_selector.js); any other word there throws `Expected 'of' keyword in ':nth-child' but got: <word>`, naming the offending token.
Solutions
- Use the `of` keyword when you want to restrict the counted siblings: ":nth-child(2 of Expression)".
- Remove the stray word if no restriction was intended: ":nth-child(2 3)" → ":nth-child(2)".
- Check the exact word named in the error message — it is the token the parser choked on.
Example fix
// before
"Statement:nth-child(2 x)"(node) { /* ... */ },
// after
"Statement:nth-child(2 of Expression)"(node) { /* ... */ }, Defensive patterns
Strategy: validation
Validate before calling
function checkNthChildKeys(key) {
const m = key.match(/:nth-child\(\s*[0-9n+-]+\s+([a-z]+)/i);
if (m && m[1] !== "of") {
throw new Error(`Expected 'of' in "${key}" but got '${m[1]}'`);
}
} Prevention
- Learn the one valid form: :nth-child(An+B of selector).
- Put nothing between the numeric argument and the closing paren except ' of <selector>'.
When it happens
Trigger: Visitor keys like "Statement:nth-child(2 3)" or "Expression:nth-child(2n+1 even)" — after the numeric argument, a word other than "of" appears before the closing parenthesis. Correct form: ":nth-child(2 of VariableDeclaration)".
Common situations: Transcribing CSS An+B syntax incorrectly (e.g. '2n+1 even' confusion); leaving a stray identifier after the step; attempting to pass a second plain argument to :nth-child.
Related errors
- Multiple selector arguments not supported here
- Empty node
- Empty selector
- Expected token ' ', but got ' '.\n\n \n ^
- Invalid RegExp pattern
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/3a7eafa1aafcdd69.
Report an issue: GitHub.
Appendix: source
Thrown at cli/js/40_lint_selector.js:657
} else if (lex.token === Token.Minus) {
node.op = "-";
lex.next();
if (lex.token === Token.Space) {
lex.next();
}
}
lex.expect(Token.Word);
node.stepOffset = +lex.value;
lex.next();
if (lex.token !== Token.BraceClose) {
lex.next(); // Space
if (lex.token === Token.Word) {
if (/** @type {string} */ (lex.value) !== "of") {
throw new Error(
`Expected 'of' keyword in ':nth-child' but got: ${lex.value}`,
);
}
lex.next();
lex.expect(Token.Space);
lex.next();
throwOnComma = true;
stack.push([]);
}
continue;
}
lex.expect(Token.BraceClose);
} else if (!node.repeat) {
// :nth-child(2) -> step is actually stepOffset
node.stepOffset = node.step - 1;View on GitHub (pinned to 9ad36f7a2c)