denoland/deno · error · Error

Expected 'of' keyword in ':nth-child' but got: ${lex.value}

Error message

Expected 'of' keyword in ':nth-child' but got: ${lex.value}

What it means

Thrown in the :nth-child parsing branch (cli/js/40_lint_selector.js) when the parser accepts an 'An+B of S' form and, after the step offset, encounters a word that is not the literal keyword 'of'. The 'of' keyword introduces the selector whose nth match counts, e.g. :nth-child(2 of VariableDeclarator).

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 89f33cbef2)

Solutions

  1. Use the exact form :nth-child(N of Selector), e.g. :nth-child(2 of VariableDeclarator)
  2. If you meant a pure positional match with no selector, keep just the number: :nth-child(2)

Example fix

// before
":nth-child(2 VariableDeclarator)"(node) {},

// after
":nth-child(2 of VariableDeclarator)"(node) {},
Defensive patterns

Strategy: validation

Validate before calling

function validNthChild(sel) {
  return sel.replace(/:nth-child\(([^)]*)\)/g, (_, arg) => {
    if (!/^(?:\d+|\d+ of .+)$/.test(arg.trim())) throw new Error(`bad :nth-child arg: '${arg}'`);
    return _;
  });
}

Prevention

When it happens

Trigger: Selectors like ":nth-child(2 odd)", ":nth-child(2 n of X)", or any word other than 'of' after the offset inside :nth-child(...). Also a typo'd keyword such as 'Of' (case matters).

Common situations: Copying CSS :nth-child(an+b [of S]) syntax that this parser only partially supports; writing :nth-child(2n) expecting the CSS '2n' step form; putting a bare type name directly after the number without the 'of' keyword.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/3a7eafa1aafcdd69. Report an issue: GitHub.