jhy/jsoup · error · IllegalStateException

Queue did not match expected sequence

Error message

Queue did not match expected sequence

What it means

Thrown by TokenQueue.consume(String) when the queue's head does not start with the requested sequence. It is a fail-fast variant of a failed match: the caller skipped the required matches(seq) pre-check (or ignored its result), so consume would otherwise silently desynchronize the parse. The faulty input is the remaining query/HTML text at the reader's current position.

Solutions

  1. Guard the call with a positive match (e.g. matchChained(seq)) before consuming, as the javadoc requires.
  2. Use a non-throwing matcher such as matchesIgnoreCase() and handle the negative branch explicitly.
  3. If the sequence is optional, check matches() first and only consume on a positive match.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/main/java/org/jsoup/parser/TokenQueue.java:118 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/1975eddc20baef31. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/jsoup/parser/TokenQueue.java:118

    }

    /**
     Test if the queue matches a tag word character (letter or digit).
     @return if matches a word character
     */
    public boolean matchesWord() {
        return Character.isLetterOrDigit(reader.current());
    }

    /**
     Consumes the supplied sequence of the queue, case-insensitively. If the queue does not start with the supplied
     sequence, will throw an illegal state exception -- but you should be running match() against that condition.

     @param seq sequence to remove from head of queue.
     */
    public void consume(String seq) {
        boolean found = reader.matchConsumeIgnoreCase(seq);
        if (!found) throw new IllegalStateException("Queue did not match expected sequence");
    }

    /**
     Pulls a string off the queue, up to but exclusive of the match sequence, or to the queue running out.
     @param seq String to end on (and not include in return, but leave on queue). <b>Case-sensitive.</b>
     @return The matched data consumed from queue.
     */
    public String consumeTo(String seq) {
        return reader.consumeTo(seq);
    }

    /**
     Consumes to the first sequence provided, or to the end of the queue. Leaves the terminator on the queue.
     @param seq any number of terminators to consume to. <b>Case-insensitive.</b>
     @return consumed string
     */
    public String consumeToAny(String... seq) {
        StringBuilder sb = StringUtil.borrowBuilder();

View on GitHub (pinned to 9851ac5d9c)