jhy/jsoup · error · Selector.SelectorParseException

null

Error message

null

What it means

A selector parse failure surfaced by QueryParser.parse: the message is literally the string "null" because the underlying exception carried no detail (null message). It wraps any low-level failure (empty input, illegal state) encountered while parsing a CSS query into jsoup's public Selector.SelectorParseException, so it signals an invalid/unparseable selector rather than a runtime condition of the document.

Solutions

  1. Catch Selector.SelectorParseException around Selector.parse / Elements.select and validate the query string before retrying.
  2. Inspect the wrapped cause; the 'null' message means the original exception had no message, so the cause chain holds the detail.
  3. Sanitize user-supplied selectors: reject empty strings and characters outside the selector grammar before parsing.
Defensive patterns

Strategy: try-catch

When it happens

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

Common situations: See trigger scenarios.


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

Appendix: source

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

        query = trimAsciiWhitespace(query);
        this.query = query;
        this.tq = new TokenQueue(query);
    }

    /**
     Parse a CSS query into an Evaluator. If you are evaluating the same query repeatedly, it may be more efficient to
     parse it once and reuse the Evaluator.

     @param query CSS query
     @return Evaluator
     @see Selector selector query syntax
     @throws Selector.SelectorParseException if the CSS query is invalid
     */
    public static Evaluator parse(String query) {
        try (QueryParser p = new QueryParser(query)) {
            return p.parse();
        } catch (IllegalArgumentException e) {
            throw new Selector.SelectorParseException(e.getMessage());
        }
    }

    /**
     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
     */

View on GitHub (pinned to 9851ac5d9c)