languagetool-org/languagetool · error · IllegalArgumentException

maxOccurrences should be between -1 and ${Byte.MAX_VALUE} bu

Error message

maxOccurrences should be between -1 and ${Byte.MAX_VALUE} but was: ${i}

What it means

PatternToken.setMaxOccurrence(int) also enforces the storage range: values must be -1 (unlimited) or between 1 and Byte.MAX_VALUE (127), since maxOccurrence is stored as a byte. Values < -1 or > 127 throw IllegalArgumentException with the offending value in the message.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternToken.java:429

   * @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 &gt;= 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)
   * @return True if the element has exception for the next scope.
   */
  public boolean hasNextException() {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Use -1 for unlimited instead of a number larger than 127.
  2. Clamp computed values to Byte.MAX_VALUE before calling setMaxOccurrence.
  3. Fix rule XML maxOccurs attributes to be within 1..127 or exactly -1.
  4. Range-validate at rule-configuration load time and fail fast with your own clearer message.

Example fix

// before
pToken.setMaxOccurrence(500);
// after
pToken.setMaxOccurrence(-1); // unlimited, or clamp: Math.min(500, Byte.MAX_VALUE)
Defensive patterns

Strategy: validation

Validate before calling

int safeMax = (maxOccurrence < -1) ? -1 : Math.min(maxOccurrence, Byte.MAX_VALUE);
pToken.setMaxOccurrence(safeMax);

Type guard

boolean isValidMaxRange(int i) { return i >= -1 && i <= Byte.MAX_VALUE && i != 0; }

Try / catch

try {
  token.setMaxOccurrence(max);
} catch (IllegalArgumentException e) {
  token.setMaxOccurrence(-1); // fall back to unlimited
}

Prevention

When it happens

Trigger: Calling setMaxOccurrence(-2) or setMaxOccurrence(128+), directly or from parsed rule XML maxOccurs attributes during build() (see testTwoMaxOccurrencesWithAnyToken).

Common situations: Rule authors writing maxOccurs="500" to mean 'many' or 'unlimited' instead of -1; computed maximums from token counts exceeding 127; copy-pasted regex quantifiers like {2,300} translated naively.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/3087c178b6e739d4. Report an issue: GitHub.