jhy/jsoup · error · IllegalArgumentException
Range positions must be non-negative
Error message
Range positions must be non-negative
What it means
Range represents a source-position span for a node when tracking is enabled. Its private constructor requires both start and end character offsets to be >= 0; negative offsets indicate corrupt position data, so jsoup throws IllegalArgumentException('Range positions must be non-negative').
Solutions
- Clamp or validate offsets before creating the range: ensure startPos and endPos are >= 0 and startPos <= endPos
- Check the offset calculation producing negative values (e.g. subtracting a larger prefix length)
- Enable jsoup's position tracking with Parser.setTrackPosition(true) and rely on jsoup's own offsets rather than hand-built ranges
- Catch IllegalArgumentException around range construction when offsets come from untrusted computation
Example fix
// before Range r = new Range(lineMap, computedStart, computedEnd); // computedStart = -3 // after if (computedStart < 0) computedStart = 0; Range r = new Range(lineMap, Math.max(0, computedStart), Math.max(0, computedEnd));
Defensive patterns
Strategy: validation
Validate before calling
boolean validRange(int start, int end) { return start >= 0 && end >= 0 && start <= end; } Try / catch
try { Range r = makeRange(startPos, endPos); } catch (IllegalArgumentException e) { if (e.getMessage().contains("non-negative")) { /* fix offsets or skip */ } throw e; } Prevention
- Clamp computed offsets with Math.max(0, x)
- Verify offset arithmetic for sign errors
- Rely on jsoup's trackPosition output instead of manual offsets
- Unit-test position bookkeeping with edge cases (start of file, empty nodes)
When it happens
Trigger: Constructing a Range (directly or via node source position setters / Line-Number tracking) with a negative startPos or endPos, usually from a miscomputed offset in custom parsing or node-movement code.
Common situations: Custom DocumentType/Node position bookkeeping that subtracts offsets incorrectly, integration code copying ranges between documents, or off-by-one/negative results from upstream offset math.
Related errors
- Attribute range positions must be non-negative
- Pattern syntax error:
- Pattern complexity error
- Pattern syntax error:
- Object must not be null
AI-assisted analysis of jhy/jsoup@9851ac5d9c (2026-09-08).
Data as JSON: /api/errors/73cbe17a18ae5e83.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/org/jsoup/nodes/Range.java:42
private final int startPos;
private final int endPos;
/**
Creates the untracked source range sentinel.
*/
private Range() {
lineMap = UnsetLineMap;
startPos = -1;
endPos = -1;
}
/**
Creates a new Range from source offsets.
*/
private Range(LineMap lineMap, int startPos, int endPos) {
this.lineMap = lineMap;
if (startPos < 0 || endPos < 0)
throw new IllegalArgumentException("Range positions must be non-negative");
this.startPos = startPos;
this.endPos = endPos;
}
/**
Get the start position of this range, with 1-based line and column coordinates.
* @return the start position.
*/
public Position start() {
return startPos == -1 ? UntrackedPos : position(startPos);
}
/**
Get the starting source offset of this range.
@return the 0-based start source offset.
@since 1.17.1
*/
public int startPos() {View on GitHub (pinned to 9851ac5d9c)