languagetool-org/languagetool · error · IllegalArgumentException
WordWithDeterminerFilter: Index out of bounds in " + match.g
Error message
WordWithDeterminerFilter: Index out of bounds in " + match.getRule().getFullId() + ", wordFrom: " + posWord
What it means
WordWithDeterminerFilter.acceptRuleMatch validates the 1-based 'wordFrom' filter argument against the matched pattern tokens and throws this IllegalArgumentException when posWord is < 1 or greater than patternTokens.length, meaning the rule references a word token position outside the pattern. (Note: the following posDeterminer check has a copy-paste bug — it prints posWord in its message.)
Source
Thrown at languagetool-language-modules/fr/src/main/java/org/languagetool/rules/fr/WordWithDeterminerFilter.java:64
private static final List<String> exceptionsDeterminer =
Arrays.asList("bels", "fols", "mols", "nouvels");
private static final String categoryToCheck = "CAT_ELISION";
private static final List<String> rulesToCheck = Arrays.asList("CET_CE", "CE_CET", "MA_VOYELLE", "MON_NFS", "VIEUX");
@Override
public RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> arguments, int patternTokenPos,
AnalyzedTokenReadings[] patternTokens, List<Integer> tokenPositions) throws IOException {
JLanguageTool lt = Languages.getLanguageForShortCode("fr").createDefaultJLanguageTool();
String wordFrom = getRequired("wordFrom", arguments);
String determinerFrom = getRequired("determinerFrom", arguments);
int posWord = 0;
int posDeterminer = 0;
if (wordFrom != null && determinerFrom != null) {
posWord = Integer.parseInt(wordFrom);
if (posWord < 1 || posWord > patternTokens.length) {
throw new IllegalArgumentException("WordWithDeterminerFilter: Index out of bounds in "
+ match.getRule().getFullId() + ", wordFrom: " + posWord);
}
posDeterminer = Integer.parseInt(determinerFrom);
if (posDeterminer < 1 || posDeterminer > patternTokens.length) {
throw new IllegalArgumentException("WordWithDeterminerFilter: Index out of bounds in "
+ match.getRule().getFullId() + ", posDeterminer: " + posWord);
}
} else {
throw new IllegalArgumentException("WordWithDeterminerFilter: undefined parameters wordFrom or determinerFrom in "
+ match.getRule().getFullId());
}
AnalyzedTokenReadings atrDeterminer = patternTokens[posDeterminer - 1];
AnalyzedTokenReadings atrWord = patternTokens[posWord - 1];
boolean isDeterminerCapitalized = StringTools.isCapitalizedWord(atrDeterminer.getToken());
boolean isWordCapitalized = StringTools.isCapitalizedWord(atrWord.getToken());
boolean isDeterminerAllupper = StringTools.isAllUppercase(atrDeterminer.getToken())
&& !atrDeterminer.getToken().equalsIgnoreCase("L'");
boolean isWordAllupper = StringTools.isAllUppercase(atrWord.getToken());View on GitHub (pinned to 2e990059ce)
Solutions
- Set wordFrom to the correct 1-based token index within the pattern's length.
- Renumber wordFrom/determinerFrom together after every pattern change and add a rule test.
- Fix the adjacent bug so the posDeterminer error message prints posDeterminer, avoiding misleading diagnostics later.
Example fix
<!-- before: pattern has 3 tokens, arg points to 6 --> <filter class="...WordWithDeterminerFilter" args="wordFrom:6 determinerFrom:1"/> <!-- after --> <filter class="...WordWithDeterminerFilter" args="wordFrom:2 determinerFrom:1"/>
Defensive patterns
Strategy: validation
Validate before calling
int wordFrom = Integer.parseInt(args.get("wordFrom"));
int patternLen = patternTokens.length;
if (wordFrom < 1 || wordFrom > patternLen) {
throw new IllegalArgumentException("wordFrom must be 1.." + patternLen);
} Try / catch
try { return filter.acceptRuleMatch(match, args, pos, tokens, tp); } catch (IllegalArgumentException e) { LOG.error("Rule " + match.getRule().getFullId() + ": " + e.getMessage()); return match; } Prevention
- Ensure wordFrom is a 1-based index within the pattern's token count.
- Renumber wordFrom/determinerFrom after pattern edits.
- Fix the diagnostic bug that prints posWord in the posDeterminer error message to avoid confusion while debugging.
When it happens
Trigger: A rule declares "wordFrom:N" where N is 0, negative, or larger than the number of tokens matched by the rule's <pattern>, evaluated when the rule match is post-processed by the filter.
Common situations: Renumbering mistakes after pattern edits; sharing args across rules with shorter patterns; confusion between the two positional args leading to swapped values.
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
- ConfusionCheckFilter: Index out of bounds in " + match.getRu
- ConfusionCheckFilter: Index out of bounds in " + match.getRu
- Set only 'weekDay' and 'date' for " + DMYDateCheckFilter.cla
- WordWithDeterminerFilter: Index out of bounds in " + match.g
- WordWithDeterminerFilter: undefined parameters wordFrom or d
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/bd10abf901cd98bb.
Report an issue: GitHub.