languagetool-org/languagetool · error · IllegalArgumentException
maxOccurrences may not be 0
Error message
maxOccurrences may not be 0
What it means
PatternToken.setMaxOccurrence(int) rejects 0 outright: a token element must occur at least once or be declared optional via min occurrence, never 'zero times max'. Any call with i == 0 throws IllegalArgumentException before the range check.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternToken.java:426
/**
* The minimum number of times this element may occur.
* @param i currently only {@code 0} and {@code 1} are supported
*/
public void setMinOccurrence(int i) {
if (i != 0 && i != 1) {
throw new IllegalArgumentException("minOccurrences must be 0 or 1: " + i);
}
setFlag(MAY_BE_OMITTED_MASK, i == 0);
}
/**
* The maximum number of times this element may occur.
* @param i a number >= 1 or {@code -1} for unlimited occurrences
*/
public void setMaxOccurrence(int i) {
if (i == 0) {
throw new IllegalArgumentException("maxOccurrences may not be 0");
}
if (i < -1 || i > Byte.MAX_VALUE) {
throw new IllegalArgumentException("maxOccurrences should be between -1 and " + Byte.MAX_VALUE + " but was: " + i);
}
maxOccurrence = (byte) i;
}
/**
* Checks if the element has an exception for a previous token.
* @return True if the element has a previous token matching exception.
*/
public boolean hasPreviousException() {
return rareFields != null && rareFields.previousExceptions.length > 0;
}
/**
* Checks if the element has an exception for a next scope.
* (only used for testing)View on GitHub (pinned to 2e990059ce)
Solutions
- Use setMinOccurrence(0) for an optional token instead of setMaxOccurrence(0).
- For truly optional repeats, call setMinOccurrence(0) plus setMaxOccurrence(n) (or -1 for unlimited).
- Fix rule XML: replace maxOccurs="0" with minOccurs="0" and a sensible max.
- Add a pre-call check: if (max == 0) treat as optional-token config instead.
Example fix
// before pToken.setMaxOccurrence(0); // after pToken.setMinOccurrence(0); pToken.setMaxOccurrence(-1); // optional, unlimited
Defensive patterns
Strategy: validation
Validate before calling
if (maxOccurrence == 0) {
pToken.setMinOccurrence(0); // optional token instead
} else {
pToken.setMaxOccurrence(maxOccurrence);
} Type guard
boolean isValidMax(int i) { return i != 0; } Try / catch
try {
token.setMaxOccurrence(max);
} catch (IllegalArgumentException e) {
token.setMinOccurrence(0); // interpret max=0 as optional
} Prevention
- Never encode optionality with max=0; use setMinOccurrence(0).
- Sanitize quantifier math so max cannot compute to 0.
- Fix rule XML maxOccurs="0" to minOccurs="0" plus a valid max.
- Add unit tests for optional-token rules.
When it happens
Trigger: Calling setMaxOccurrence(0), directly or via build() when rule XML specifies maxOccurs="0" or a builder passes 0 (see testZeroMinOccurrences2 / testZeroMinTwoMaxOccurrences).
Common situations: Authors who intend an optional token writing max="0" instead of min="0"; auto-generated rules from quantifier math where max computes to 0; confusion with regex {0} semantics.
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}
- minOccurrences must be 0 or 1: ${i}
- maxOccurrences should be between -1 and ${Byte.MAX_VALUE} bu
- minOccurrence must be >= 0: ${minOccurrence}
- Set only 'weekDay' and 'date' for " + YMDDateCheckFilter.cla
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/1d190979f01db4bd.
Report an issue: GitHub.