languagetool-org/languagetool · error · RuntimeException

Only 3grams and 4grams are supported

Error message

Only 3grams and 4grams are supported

What it means

ConfusionProbabilityRule checks whether a confused word pair can be corrected using an n-gram language model. It only implements 3-gram and 4-gram probability lookups; any other n-gram size configured for the rule hits the else branch and throws this RuntimeException.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/ngrams/ConfusionProbabilityRule.java:332

      if (s.getString().equalsIgnoreCase(token.token)) {
        return s;
      }
    }
    throw new RuntimeException("Not found in set '" + confusionSet + "': " + token);
  }

  private ConfusionString getBetterAlternativeOrNull(GoogleToken token, List<GoogleToken> tokens, ConfusionString otherWord, long factor) {
    String word = token.token;
    double p1;
    double p2;
    if (grams == 3) {
      p1 = LanguageModelUtils.get3gramProbabilityFor(language, lm, token, tokens, word);
      p2 = LanguageModelUtils.get3gramProbabilityFor(language, lm, token, tokens, otherWord.getString());
    } else if (grams == 4) {
      p1 = LanguageModelUtils.get4gramProbabilityFor(language, lm, token, tokens, word);
      p2 = LanguageModelUtils.get4gramProbabilityFor(language, lm, token, tokens, otherWord.getString());
    } else {
      throw new RuntimeException("Only 3grams and 4grams are supported");
    }
    debug("%.90f <- P(" + word + ") \n", p1);
    debug("%.90f <- P(" + otherWord + ")\n", p2);
    return p2 >= MIN_PROB && p2 > p1 * factor ? otherWord : null;
  }

  private void debug(String message, Object... vars) {
    if (DEBUG) {
      System.out.printf(Locale.ENGLISH, message, vars);
    }
  }

  @Override
  public List<DisambiguationPatternRule> getAntiPatterns() {
    return antiPatterns;
  }

  private static class PathAndLanguage {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Set the rule's n-gram size to 3 or 4 (match the values supported by LanguageModelUtils.get3gramProbabilityFor/get4gramProbabilityFor)
  2. If you need 2-gram support, add an 'else if (grams == 2)' branch using LanguageModelUtils.get2gramProbabilityFor
  3. Check the confusion rule XML for 'norm' or ngram attributes and correct them to supported values

Example fix

// before
} else {
  throw new RuntimeException("Only 3grams and 4grams are supported");
}
// after
} else if (grams == 2) {
  p1 = LanguageModelUtils.get2gramProbabilityFor(language, lm, token, tokens, word);
  p2 = LanguageModelUtils.get2gramProbabilityFor(language, lm, token, tokens, otherWord.getString());
} else {
  throw new RuntimeException("Only 3grams and 4grams are supported");
}
Defensive patterns

Strategy: validation

Validate before calling

if (grams != 3 && grams != 4) {
  throw new IllegalArgumentException("grams must be 3 or 4, got: " + grams);
}

Try / catch

try {
  alternative = rule.betterAlternative(...);
} catch (RuntimeException e) {
  if (e.getMessage().contains("Only 3grams and 4grams are supported")) {
    log.error("Unsupported ngram size in confusion rule config");
  } else { throw e; }
}

Prevention

When it happens

Trigger: Constructing or configuring ConfusionProbabilityRule with a 'grams' value (the n-gram order from the rule's maxNgram settings) that is not 3 or 4, then calling betterAlternative/getBetterAlternativeOrNull during rule evaluation.

Common situations: Custom confusion-pair rule XML that declares unsupported ngram sizes (e.g. 2 or 5), copying a rule configuration from a different rule type, or an upstream settings change that altered the configured grams value.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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