{"record":{"id":"4c45d90eef1e87e1","repo":"languagetool-org/languagetool","slug":"only-3grams-and-4grams-are-supported","errorCode":null,"errorMessage":"Only 3grams and 4grams are supported","messagePattern":"Only 3grams and 4grams are supported","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/ngrams/ConfusionProbabilityRule.java","lineNumber":332,"sourceCode":"      if (s.getString().equalsIgnoreCase(token.token)) {\n        return s;\n      }\n    }\n    throw new RuntimeException(\"Not found in set '\" + confusionSet + \"': \" + token);\n  }\n\n  private ConfusionString getBetterAlternativeOrNull(GoogleToken token, List<GoogleToken> tokens, ConfusionString otherWord, long factor) {\n    String word = token.token;\n    double p1;\n    double p2;\n    if (grams == 3) {\n      p1 = LanguageModelUtils.get3gramProbabilityFor(language, lm, token, tokens, word);\n      p2 = LanguageModelUtils.get3gramProbabilityFor(language, lm, token, tokens, otherWord.getString());\n    } else if (grams == 4) {\n      p1 = LanguageModelUtils.get4gramProbabilityFor(language, lm, token, tokens, word);\n      p2 = LanguageModelUtils.get4gramProbabilityFor(language, lm, token, tokens, otherWord.getString());\n    } else {\n      throw new RuntimeException(\"Only 3grams and 4grams are supported\");\n    }\n    debug(\"%.90f <- P(\" + word + \") \\n\", p1);\n    debug(\"%.90f <- P(\" + otherWord + \")\\n\", p2);\n    return p2 >= MIN_PROB && p2 > p1 * factor ? otherWord : null;\n  }\n\n  private void debug(String message, Object... vars) {\n    if (DEBUG) {\n      System.out.printf(Locale.ENGLISH, message, vars);\n    }\n  }\n\n  @Override\n  public List<DisambiguationPatternRule> getAntiPatterns() {\n    return antiPatterns;\n  }\n\n  private static class PathAndLanguage {","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/ngrams/ConfusionProbabilityRule.java#L314-L350","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set the rule's n-gram size to 3 or 4 (match the values supported by LanguageModelUtils.get3gramProbabilityFor/get4gramProbabilityFor)","If you need 2-gram support, add an 'else if (grams == 2)' branch using LanguageModelUtils.get2gramProbabilityFor","Check the confusion rule XML for 'norm' or ngram attributes and correct them to supported values"],"exampleFix":"// before\n} else {\n  throw new RuntimeException(\"Only 3grams and 4grams are supported\");\n}\n// after\n} else if (grams == 2) {\n  p1 = LanguageModelUtils.get2gramProbabilityFor(language, lm, token, tokens, word);\n  p2 = LanguageModelUtils.get2gramProbabilityFor(language, lm, token, tokens, otherWord.getString());\n} else {\n  throw new RuntimeException(\"Only 3grams and 4grams are supported\");\n}","handlingStrategy":"validation","validationCode":"if (grams != 3 && grams != 4) {\n  throw new IllegalArgumentException(\"grams must be 3 or 4, got: \" + grams);\n}","typeGuard":null,"tryCatchPattern":"try {\n  alternative = rule.betterAlternative(...);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Only 3grams and 4grams are supported\")) {\n    log.error(\"Unsupported ngram size in confusion rule config\");\n  } else { throw e; }\n}","preventionTips":["Assert grams ∈ {3,4} at rule construction time","Keep confusion rule XML attributes aligned with LanguageModelUtils capabilities","Add a unit test per confusion rule config that exercises betterAlternative once"],"tags":["ngram","language-model","rule-configuration","runtime-exception"],"backgroundTag":"unsupported-operation","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}