languagetool-org/languagetool · error · IllegalArgumentException
RuleFilter: Index out of bounds in ${match.getRule().getFull
Error message
RuleFilter: Index out of bounds in ${match.getRule().getFullId()}, value: ${fromStr} What it means
RuleFilter.getPosition() converts a position value like '1', '2marker' or 'rel:n' from the rule XML into a zero-based token index for the matched pattern. It throws IllegalArgumentException when the computed index is less than 1 or greater than the number of pattern tokens, i.e. the referenced position does not exist in the rule pattern.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/RuleFilter.java:103
}
protected int getPosition(String fromStr, AnalyzedTokenReadings[] patternTokens, RuleMatch match) {
int i;
if (fromStr.startsWith("marker")) {
i = 0;
while (i < patternTokens.length && patternTokens[i].getStartPos() < match.getFromPos()
|| patternTokens[i].isSentenceStart()) {
i++;
}
i++;
if (fromStr.length()>6) {
i += Integer.parseInt(fromStr.replace("marker", ""));
}
} else {
i = Integer.parseInt(fromStr);
}
if (i < 1 || i > patternTokens.length) {
throw new IllegalArgumentException("RuleFilter: Index out of bounds in "
+ match.getRule().getFullId() + ", value: " + fromStr);
}
return i - 1;
}
protected boolean isMatchAtSentenceStart(AnalyzedTokenReadings[] tokens, RuleMatch match) {
int i = 0;
while (i < tokens.length && tokens[i].getStartPos() < match.getFromPos()) {
i++;
}
while (i > 0 && StringTools.isPunctuationMark(tokens[i].getToken())) {
i--;
}
return i == 0;
}
// when there's a 'skip', we need to adapt the reference number
protected int getSkipCorrectedReference(List<Integer> tokenPositions, int refNumber) {View on GitHub (pinned to 2e990059ce)
Solutions
- Count the tokens in the rule's <pattern> and set the position attribute to a value between 1 and that count
- If you recently changed the pattern, recompute all position attributes in the filter/tokenFilter elements
- Check marker/rel offset arithmetic in the filter source; ensure the referenced marker token exists
- Remember getPosition returns i-1; verify you are not double-adjusting an already 0-based value
Example fix
// before (XML) <pattern> <token regexp="yes">be</token> </pattern> <filter class="MyFilter" args="position:3"/> // after (XML) <pattern> <token regexp="yes">be</token> </pattern> <filter class="MyFilter" args="position:1"/>
Defensive patterns
Strategy: validation
Validate before calling
int patternTokenCount = countPatternTokens(ruleXmlPattern);
int pos = Integer.parseInt(args.get("position").replace("marker", ""));
if (pos < 1 || pos > patternTokenCount) throw new IllegalStateException("position " + pos + " outside pattern of size " + patternTokenCount); Type guard
boolean isValidPosition(String s, int n) { try { int i = Integer.parseInt(s); return i >= 1 && i <= n; } catch (NumberFormatException e) { return false; } } Try / catch
try {
int idx = getPosition(match, patternTokens, fromStr);
} catch (IllegalArgumentException e) {
LOG.error("Filter position invalid for {}: {}", match.getRule().getFullId(), e.getMessage());
return match; // or rethrow in strict mode
} Prevention
- After any change to a rule's <pattern>, re-check every position attribute in filters
- Remember positions in XML are 1-based; getPosition returns a 0-based index
- Unit-test each pattern rule with its filter so out-of-range positions are caught early
- Avoid marker-based offsets unless the <marker> element is present
When it happens
Trigger: An XML attribute such as tokenFilter pos='5' (or fromStr from marker/rel syntax) points beyond the number of tokens in the <pattern> of the rule, or evaluates to 0/negative after the 'marker'/rel offset arithmetic.
Common situations: Editing a rule and deleting or adding tokens to the pattern without updating the filter position; off-by-one confusion between the 1-based XML numbering and the returned 0-based index; using marker-based offsets in a rule without a <marker> element.
Related errors
- Missing key '${key}'
- AbstractAdvancedSynthesizerFilter only works with pattern ru
- ConfusionCheckFilter: Index out of bounds in " + match.getRu
- ConfusionCheckFilter: Index out of bounds in " + match.getRu
- ConfusionCheckFilter: Index out of bounds in " + match.getRu
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/ed0e8b428327293b.
Report an issue: GitHub.