eslint/eslint · error · SyntaxError
Syntax error in selector "${selector}" at position ${err.loc
Error message
Syntax error in selector "${selector}" at position ${err.location.start.offset}: ${err.message} What it means
Thrown by tryParseSelector when esquery fails to parse an AST selector string and the resulting error carries a location object (err.location.start.offset). The wrapper re-throws as a SyntaxError with the original selector, the 0-based offset of the failure, and esquery's message, chaining the original error as cause. Selectors that fail without a location are re-thrown unchanged.
Source
Thrown at lib/linter/esquery.js:272
return null;
}
/**
* Parses a raw selector string, and throws a useful error if parsing fails.
* @param {string} selector The selector string to parse.
* @returns {Object} An object (from esquery) describing the matching behavior of this selector
* @throws {Error} An error if the selector is invalid
*/
function tryParseSelector(selector) {
try {
return esquery.parse(selector);
} catch (err) {
if (
err.location &&
err.location.start &&
typeof err.location.start.offset === "number"
) {
throw new SyntaxError(
`Syntax error in selector "${selector}" at position ${err.location.start.offset}: ${err.message}`,
{
cause: err,
},
);
}
throw err;
}
}
/**
* Parses a raw selector string, and returns the parsed selector along with specificity and type information.
* @param {string} source A raw AST selector
* @returns {ESQueryParsedSelector} A selector descriptor
*/
function parse(source) {
if (selectorCache.has(source)) {
return selectorCache.get(source);View on GitHub (pinned to f131c034ad)
Solutions
- Read the reported offset and fix the selector at that character position.
- Validate selectors in isolation with require('esquery').parse(sel) during rule authoring.
- Cross-check the selector against the esquery syntax reference supported by your ESLint version.
- If building selectors dynamically, sanitize and unit-test the generated string.
Example fix
// before (malformed selector)
context.report({ node, message: 'x' });
// rule defined with selector: 'FunctionDeclaration >'
// after
// selector: 'FunctionDeclaration > BlockStatement' Defensive patterns
Strategy: try-catch
Validate before calling
function isValidSelector(selector) {
try { require('esquery').parse(selector.replace(/:exit$/u, '')); return true; } catch { return false; }
} Type guard
function isParsableSelector(selector) { return typeof selector === 'string' && isValidSelector(selector); } Try / catch
try { const parsed = require('esquery').parse(selector); } catch (err) {
if (err.location && typeof err.location.start?.offset === 'number') {
throw new SyntaxError(`Bad selector at offset ${err.location.start.offset}: ${err.message}`, { cause: err });
}
throw err;
} Prevention
- Unit-test custom rule selectors with esquery.parse during authoring.
- Cross-check selector syntax against the esquery version bundled with your ESLint.
- When building selectors dynamically, sanitize and validate the generated string before use.
When it happens
Trigger: Writing an invalid esquery selector in a rule's visitor: 'FunctionDeclaration >', ':not(', 'Identifier[', or any malformed CSS-like selector. The error surfaces when ESLint parses rule selectors at load/config time.
Common situations: Authoring a custom ESLint rule with a typo'd selector; using esquery syntax not supported by the bundled version; copy-paste from CSS docs introducing unsupported pseudo-classes; a dynamic selector built from user input that produced malformed output.
Related errors
- Unknown class name: ${className}
- Rule's `meta.schema` must be an array or object
- ESLINT_INVALID_RULE_OPTIONS_SCHEMA
- Key "rules": Key "${ruleId}": Key "meta": Key "languages": E
- Key "rules": Key "${ruleId}": Key "meta": Key "languages": E
AI-assisted analysis of eslint/eslint@f131c034ad (2026-08-03).
Data as JSON: /data/errors/ce1db1c0c18ac80f.json.
Report an issue: GitHub.