jhy/jsoup · error · IllegalArgumentException
CSS identifier expected, but end of input found
Error message
CSS identifier expected, but end of input found
What it means
Selector-syntax error raised by TokenQueue.consumeCssIdentifier: the queue was positioned at a CSS identifier (e.g. after a '#' or '.' in a selector) but input ended before any identifier character appeared. Typically caused by a truncated query such as "div#" or ".class>" with nothing following, i.e. malformed user-supplied CSS rather than an internal bug.
Solutions
- Validate/complete the CSS selector string before passing it to jsoup; ensure every '#'/'.' prefix is followed by a name.
- Catch Selector.SelectorParseException around Selector.parse and surface a 'selector is incomplete' message to the user.
- Escape special characters in identifiers (e.g. numeric-leading IDs as \31) so the identifier consumes at least one character.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/main/java/org/jsoup/parser/TokenQueue.java:327 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/1e26d2f97151eaa5.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/org/jsoup/parser/TokenQueue.java:327
*/
public String consumeElementSelector() {
return consumeEscapedCssIdentifier(ElementSelectorChars);
}
private static final char[] ElementSelectorChars = {'*', '|', '_', '-'};
/**
Consume a CSS identifier (ID or class) off the queue.
<p>Note: For backwards compatibility this method supports improperly formatted CSS identifiers, e.g. {@code 1} instead
of {@code \31}.</p>
@return The unescaped identifier.
@throws IllegalArgumentException if an invalid escape sequence was found. Afterward, the state of the TokenQueue
is undefined.
@see <a href="https://www.w3.org/TR/css-syntax-3/#consume-name">CSS Syntax Module Level 3, Consume an ident sequence</a>
@see <a href="https://www.w3.org/TR/css-syntax-3/#typedef-ident-token">CSS Syntax Module Level 3, ident-token</a>
*/
public String consumeCssIdentifier() {
if (isEmpty()) throw new IllegalArgumentException("CSS identifier expected, but end of input found");
// Fast path for CSS identifiers that don't contain escape sequences.
String identifier = reader.consumeMatching(TokenQueue::isIdent);
char c = current();
if (c != Esc && c != Unicode_Null) {
// If we didn't end on an Esc or a Null, we consumed the whole identifier
return identifier;
}
// An escape sequence was found. Use a StringBuilder to store the decoded CSS identifier.
StringBuilder out = StringUtil.borrowBuilder();
if (!identifier.isEmpty()) {
// Copy the CSS identifier up to the first escape sequence.
out.append(identifier);
}
while (!isEmpty()) {
c = current();View on GitHub (pinned to 9851ac5d9c)