languagetool-org/languagetool · error · IllegalArgumentException

WordWithDeterminerFilter: Index out of bounds in " + match.g

Error message

WordWithDeterminerFilter: Index out of bounds in " + match.getRule().getFullId() + ", posDeterminer: " + posWord

What it means

The French WordWithDeterminerFilter throws this IllegalArgumentException when the rule XML's 'determinerFrom' position parsed into posDeterminer is outside 1..patternTokens.length. Note the message has a copy-paste bug: it prints the posWord variable instead of posDeterminer. It signals a malformed filter configuration in a disambiguation/rule XML file, not a runtime data problem.

Source

Thrown at languagetool-language-modules/fr/src/main/java/org/languagetool/rules/fr/WordWithDeterminerFilter.java:69

  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());
    AnalyzedToken atDeterminer = getAnalyzedToken(atrDeterminer, detPattern);
    AnalyzedToken atWord = getAnalyzedToken(atrWord, wordPattern);
    if (atWord == null || atDeterminer == null) {
      throw new RuntimeException(
          "Error analyzing sentence: '" + match.getSentence().getText() + "' with rule " + match.getRule().getFullId());

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Open the rule XML with rule id = the id printed in the message and fix the determinerFrom value so it is between 1 and the number of pattern tokens.
  2. Count the tokens in the rule's <pattern> and renumber wordFrom/determinerFrom after any token additions or removals.
  3. If determinerFrom is correct but the pattern shrank, extend the pattern rather than the filter.
  4. Test the rule with LanguageTool's rule validation tests so out-of-range positions fail at build time.

Example fix

// before (rule XML)
<filter class="org.languagetool.rules.fr.WordWithDeterminerFilter" args="wordFrom:1 determinerFrom:7"/>
// after (pattern has 4 tokens)
<filter class="org.languagetool.rules.fr.WordWithDeterminerFilter" args="wordFrom:1 determinerFrom:3"/>
Defensive patterns

Strategy: validation

Validate before calling

int detFrom = Integer.parseInt(attrs.get("determinerFrom"));
if (detFrom < 1 || detFrom > patternTokens.length)
  throw new IllegalArgumentException("determinerFrom out of range: " + detFrom);

Try / catch

try { filter.acceptRuleMatch(match); } catch (IllegalArgumentException e) { log.error("Bad filter config: " + e.getMessage()); }

Prevention

When it happens

Trigger: A French XML rule using the WordWithDeterminerFilter supplies a determinerFrom attribute whose value is < 1 or greater than the number of tokens matched by the pattern; acceptRuleMatch then parses and range-checks it and throws.

Common situations: Hand-editing custom French rule XML files; off-by-one in token positions when adding/removing a token from the pattern; copying a rule and forgetting to adjust determinerFrom; porting rules between pattern definitions.

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


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