{"record":{"id":"3a7eafa1aafcdd69","repo":"denoland/deno","slug":"expected-of-keyword-in-nth-child-but-got-l","errorCode":null,"errorMessage":"Expected 'of' keyword in ':nth-child' but got: ${lex.value}","messagePattern":"Expected 'of' keyword in ':nth-child' but got: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/js/40_lint_selector.js","lineNumber":657,"sourceCode":"            } else if (lex.token === Token.Minus) {\n              node.op = \"-\";\n              lex.next();\n\n              if (lex.token === Token.Space) {\n                lex.next();\n              }\n            }\n\n            lex.expect(Token.Word);\n            node.stepOffset = +lex.value;\n            lex.next();\n\n            if (lex.token !== Token.BraceClose) {\n              lex.next(); // Space\n\n              if (lex.token === Token.Word) {\n                if (/** @type {string} */ (lex.value) !== \"of\") {\n                  throw new Error(\n                    `Expected 'of' keyword in ':nth-child' but got: ${lex.value}`,\n                  );\n                }\n\n                lex.next();\n                lex.expect(Token.Space);\n                lex.next();\n                throwOnComma = true;\n                stack.push([]);\n              }\n\n              continue;\n            }\n\n            lex.expect(Token.BraceClose);\n          } else if (!node.repeat) {\n            // :nth-child(2) -> step is actually stepOffset\n            node.stepOffset = node.step - 1;","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/js/40_lint_selector.js#L639-L675","documentation":"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.","triggerScenarios":"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)\".","commonSituations":"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.","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."],"exampleFix":"// before\n\"Statement:nth-child(2 x)\"(node) { /* ... */ },\n\n// after\n\"Statement:nth-child(2 of Expression)\"(node) { /* ... */ },","handlingStrategy":"validation","validationCode":"function checkNthChildKeys(key) {\n  const m = key.match(/:nth-child\\(\\s*[0-9n+-]+\\s+([a-z]+)/i);\n  if (m && m[1] !== \"of\") {\n    throw new Error(`Expected 'of' in \"${key}\" but got '${m[1]}'`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Learn the one valid form: :nth-child(An+B of selector).","Put nothing between the numeric argument and the closing paren except ' of <selector>'."],"tags":["deno","deno-lint","lint-plugin","selector","nth-child","parse-error"],"backgroundTag":"invalid-selector-syntax","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}