jhy/jsoup · error · Selector.SelectorParseException

Could not parse query

Error message

Could not parse query '%s': unexpected token at '%s'

What it means

Grammar error thrown by QueryParser.parse when the token stream stops at a character that does not fit the selector grammar (Selector / Combinator / SimpleSequence rules) — e.g. a stray operator, unmatched bracket, or unexpected character. The message includes the full query and the remainder where parsing failed, identifying the exact malformed input.

Solutions

  1. Inspect the remainder in the message to locate the offending character and fix the selector (e.g. stray '>', '~', or unbalanced ']').
  2. Catch Selector.SelectorParseException when queries come from user input and return a targeted syntax error.
  3. Use jsoup's documented selector syntax and validate against it before parsing.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/main/java/org/jsoup/select/QueryParser.java:82 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of jhy/jsoup@9851ac5d9c (2026-09-08). Data as JSON: /api/errors/37fabb540a899e78. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/jsoup/select/QueryParser.java:82

     Parse the query. We use this simplified expression of the grammar:
     <pre>
     SelectorGroup   ::= Selector (',' Selector)*
     Selector        ::= [ Combinator ] SimpleSequence ( Combinator SimpleSequence )*
     SimpleSequence  ::= [ TypeSelector ] ( ID | Class | Attribute | Pseudo )*
     Pseudo           ::= ':' Name [ '(' SelectorGroup ')' ]
     Combinator      ::= S+         // descendant (whitespace)
     | '>'       // child
     | '+'       // adjacent sibling
     | '~'       // general sibling
     </pre>

     See <a href="https://www.w3.org/TR/selectors-4/#grammar">selectors-4</a> for the real thing
     */
    Evaluator parse() {
        Evaluator eval = parseSelectorGroup();
        tq.consumeWhitespace();
        if (!tq.isEmpty())
            throw new Selector.SelectorParseException("Could not parse query '%s': unexpected token at '%s'", query, tq.remainder());
        return eval;
    }

    Evaluator parseSelectorGroup() {
        // SelectorGroup. Into an Or if > 1 Selector
        Evaluator left = parseSelector();
        while (tq.matchChomp(',')) {
            Evaluator right = parseSelector();
            left = or(left, right);
        }
        return left;
    }

    Evaluator parseSelector() {
        // Selector ::= [ Combinator ] SimpleSequence ( Combinator SimpleSequence )*
        tq.consumeWhitespace();

        Evaluator left;

View on GitHub (pinned to 9851ac5d9c)