languagetool-org/languagetool · error · RuntimeException

The number of forms and postags has to be the same in disamb

Error message

The number of forms and postags has to be the same in disambiguation rule with filter IsEnglishWordFilter.

What it means

IsEnglishWordFilter.acceptRuleMatch checks disambiguation-rule forms against a comma-separated 'postags' argument. When the number of comma-separated postags differs from the number of captured forms, it throws RuntimeException because forms and postags are matched index-by-index.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/IsEnglishWordFilter.java:68

  @Override
  public RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> args, int patternTokenPos,
                                   AnalyzedTokenReadings[] patternTokens, List<Integer> tokenPositions) throws IOException {

    if (tagger == null) {
      return null;
    }
    String[] formPositions = getRequired("formPositions", args).split(",");
    List<String> forms = new ArrayList<>();
    for (String formPosition : formPositions) {
      forms.add(patternTokens[getSkipCorrectedReference(tokenPositions, Integer.parseInt(formPosition))].getToken());
    }
    boolean isEnglish = true;
    String postagsStr = getOptional("postags", args);
    if (postagsStr != null) {
      String [] postags = postagsStr.split(",");
      if (postags.length != forms.size()) {
        throw new RuntimeException("The number of forms and postags has to be the same in disambiguation rule with " +
            "filter IsEnglishWordFilter.");
      }
      for (int i = 0; i < postags.length; i++) {
        isEnglish = isEnglish && wordIsTaggedWith(forms.get(i), postags[i]);
      }
    } else {
      for (int i = 0; i < forms.size(); i++) {
        isEnglish = isEnglish && wordIsTagged(forms.get(i));
      }
    }
    return (isEnglish ? match : null);
  }

  private boolean wordIsTaggedWith(String word, String postag) throws IOException {
    return tagger.tag(Collections.singletonList(word)).get(0).matchesPosTagRegex(postag);
  }

  private boolean wordIsTagged(String word) throws IOException {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Count the marked forms in the disambiguation rule and make the 'postags' attribute contain exactly that many comma-separated tags.
  2. Remove stray commas/whitespace entries in postags that create empty or extra elements.
  3. Test the rule with LanguageTool's rule-validation (e.g. validateRules) so the mismatch is caught before runtime.

Example fix

<!-- before -->
<filter class="org.languagetool.rules.IsEnglishWordFilter" args="postags:NN,VVD"/>
<!-- after (two marked forms -> two postags) -->
<filter class="org.languagetool.rules.IsEnglishWordFilter" args="postags:NN,VVD"/> <!-- ensure exactly 2 marked tokens -->
Defensive patterns

Strategy: validation

Validate before calling

int formCount = /* number of marked tokens in the disambiguation rule */;
int tagCount = postagsStr == null ? 0 : postagsStr.split(",").length;
if (postagsStr != null && tagCount != formCount) {
  throw new IllegalArgumentException("postags count (" + tagCount + ") must equal marked forms (" + formCount + ")");
}

Try / catch

try {
  return filter.acceptRuleMatch(match, args, pos, tokens, tokenPositions);
} catch (RuntimeException e) {
  throw new RuleFormatException("Invalid IsEnglishWordFilter args: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Using filter="IsEnglishWordFilter" in a disambiguation rule with a 'postags' attribute whose comma-separated tag count does not equal the number of tokens captured by the marker (forms.size()).

Common situations: Hand-writing disambiguation XML rules and forgetting a tag or adding an extra comma; adding a token to the marked phrase without updating postags; copying a rule and changing the token count only.

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/2e775e0a3a144e04. Report an issue: GitHub.