languagetool-org/languagetool · error · IllegalArgumentException
minOccurrence must be >= 0: ${minOccurrence}
Error message
minOccurrence must be >= 0: ${minOccurrence} What it means
PatternTokenBuilder.min(int) rejects negative minimum-occurrence values, throwing IllegalArgumentException when val < 0. Note the message mistakenly prints the field minOccurrence (the previous value, possibly null) instead of the parameter val — the offending input is the negative val you passed. Valid minimums are 0 or 1 once passed to the token.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternTokenBuilder.java:85
public PatternTokenBuilder csTokenRegex(String token) {
this.token = Objects.requireNonNull(token);
regexp = true;
caseSensitive = true;
return this;
}
public PatternTokenBuilder pos(String posTag) {
return pos(posTag, false);
}
public PatternTokenBuilder posRegex(String posTag) {
return pos(posTag, true);
}
/** @since 4.9 */
public PatternTokenBuilder min(int val) {
if (val < 0) {
throw new IllegalArgumentException("minOccurrence must be >= 0: " + minOccurrence);
}
minOccurrence = val;
return this;
}
/** @since 4.9 */
public PatternTokenBuilder max(int val) {
maxOccurrence = val;
return this;
}
/**
* Corresponds to {@code <marker>...</marker>} in XML. Note that there
* can be more tokens with a mark, but then must all be adjacent.
* @since 4.6
*/
public PatternTokenBuilder mark(boolean isMarked) {
this.marker = isMarked;View on GitHub (pinned to 2e990059ce)
Solutions
- Pass a non-negative value; use 0 for an optional token via min(0) combined with an appropriate max.
- Clamp before calling: Math.max(0, computedMin).
- Fix quantifier arithmetic so the minimum cannot go below 0.
- If you intended unlimited, do not use min(); configure max(-1) and set optionality separately.
Example fix
// before builder.min(count - 2); // can be negative // after builder.min(Math.max(0, count - 2));
Defensive patterns
Strategy: validation
Validate before calling
int safeMin = Math.max(0, computedMin); builder.min(safeMin);
Type guard
boolean isNonNegative(int i) { return i >= 0; } Try / catch
try {
builder.min(val);
} catch (IllegalArgumentException e) {
builder.min(0); // log the negative computed value
} Prevention
- Clamp computed minimums with Math.max(0, ...) before calling min().
- Remember the error message shows the stale field, not your input; debug with the parameter value.
- Use min(0) for optional tokens rather than negative sentinels.
- Unit-test builder chains with edge-case counts.
When it happens
Trigger: Calling new PatternTokenBuilder().min(-1) or any negative value; builders computing min counts from arithmetic that can go negative (e.g. max - n).
Common situations: Quantifier arithmetic producing negative minimums; off-by-one in code that decrements counts; passing a sentinel -1 to mean 'unlimited' (which belongs in min()/max() semantics differently here).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- 'skip' should be between -1 and ${Byte.MAX_VALUE}
- maxOccurrences should be between -1 and ${Byte.MAX_VALUE} bu
- minOccurrences must be 0 or 1: ${i}
- maxOccurrences may not be 0
- Set only 'weekDay' and 'date' for " + YMDDateCheckFilter.cla
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/5051f0cba546957d.
Report an issue: GitHub.