denoland/deno · error · Error

Expected token ' ', but got ' '.\n\n \n ^

Error message

Expected token '${token}', but got '${this.token}'.\n\n${this.input}\n${" ".repeat(this.i)}^

What it means

The selector parser's expect() throws when the token stream does not match the grammar — for example a missing word after ':' or '.', or an empty :nth-child() argument (cli/js/40_lint_selector.js). The message includes the expected and actual token values, which are numeric internal Token enum codes rather than readable names, plus the full selector text and a caret (^) marking the lexer's position in it — use the caret to locate the syntax error.

Solutions

  1. Look at the caret line in the message — it points at the exact character where parsing failed; fix the key there.
  2. Remove empty pseudo arguments (":nth-child()" → ":nth-child(1)") and dangling '.' or ':' tokens.
  3. Simplify the key to a plain node type ("VariableDeclaration") and re-add parts one at a time until the broken fragment is isolated.
  4. Add a plugin unit test that exercises every visitor key so syntax errors surface in CI.

Example fix

// before
"Expression."(node) { /* ... */ },
":nth-child()"(node) { /* ... */ },

// after
"Expression"(node) { /* ... */ },
":nth-child(1)"(node) { /* ... */ },
Defensive patterns

Strategy: validation

Validate before calling

// Cheap pre-flight for the common malformed-key shapes:
function looksMalformed(key) {
  return /[.:]\s*$/.test(key) || /:nth-child\(\s*\)/.test(key) || /\[[^\]]*$/.test(key);
}

Prevention

When it happens

Trigger: Visitor keys such as "a." (a word is expected after the dot), ":" alone (a word is expected after the colon), ":nth-child()" (a word is expected but the closing brace comes), or "[attr=" (missing value/closing bracket) — thrown during selector parsing when the rule registers.

Common situations: Typos in hand-written selector keys; trailing separators left after editing; copy-pasting CSS selectors whose grammar differs (empty pseudo arguments); refactoring keys and leaving dangling tokens.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/2920fa88c755a6bb. Report an issue: GitHub.

Appendix: source

Thrown at cli/js/40_lint_selector.js:140

  i = -1;

  value = "";

  /**
   * @param {string} input
   */
  constructor(input) {
    this.input = input;
    this.step();
    this.next();
  }

  /**
   * @param {number} token
   */
  expect(token) {
    if (this.token !== token) {
      throw new Error(
        `Expected token '${token}', but got '${this.token}'.\n\n${this.input}\n${
          " ".repeat(this.i)
        }^`,
      );
    }
  }

  /**
   * @param {number} token
   */
  readAsWordUntil(token) {
    const s = this.i;
    while (this.token !== Token.EOF && this.token !== token) {
      this.next();
    }

    this.start = s;
    this.end = this.i - 1;

View on GitHub (pinned to 9ad36f7a2c)