{"record":{"id":"dc963f538ee31cfd","repo":"languagetool-org/languagetool","slug":"language","errorCode":null,"errorMessage":"Language ","messagePattern":"Language ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"languagetool-dev/src/main/java/org/languagetool/dev/bigdata/ConfusionRuleEvaluator.java","lineNumber":74,"sourceCode":"  private static final List<Long> EVAL_FACTORS = Arrays.asList(10L, 100L, 1_000L, 10_000L, 100_000L, 1_000_000L, 10_000_000L);\n  private static final int MAX_SENTENCES = 1000;\n\n  private final Language language;\n  private final boolean caseSensitive;\n  private final boolean bothDirections;  // replace A by B and vice versa?\n  private final ConfusionProbabilityRule rule;\n  private final Map<Long, RuleEvalValues> evalValues = new HashMap<>();\n\n  private boolean verbose = true;\n\n  ConfusionRuleEvaluator(Language language, LanguageModel languageModel, boolean caseSensitive, boolean bothDirections) {\n    this.language = language;\n    this.caseSensitive = caseSensitive;\n    this.bothDirections = bothDirections;\n    try {\n      List<Rule> rules = language.getRelevantLanguageModelRules(JLanguageTool.getMessageBundle(), languageModel, null);\n      if (rules == null) {\n        throw new RuntimeException(\"Language \" + language + \" doesn't seem to support a language model\");\n      }\n      ConfusionProbabilityRule foundRule = null;\n      for (Rule rule : rules) {\n        if (rule.getId().equals(ConfusionProbabilityRule.RULE_ID)) {\n          foundRule = (ConfusionProbabilityRule)rule;\n          break;\n        }\n      }\n      if (foundRule == null) {\n        throw new RuntimeException(\"Language \" + language + \" has no language model rule with id \" + ConfusionProbabilityRule.RULE_ID);\n      } else {\n        this.rule = foundRule;\n      }\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    }\n  }\n  ","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-dev/src/main/java/org/languagetool/dev/bigdata/ConfusionRuleEvaluator.java#L56-L92","documentation":"ConfusionRuleEvaluator's constructor asks the language for its language-model-based rules via language.getRelevantLanguageModelRules(...). If that returns null, the language has no language model support at all, so evaluation of confusion rules is impossible and the constructor throws 'Language X doesn't seem to support a language model'.","triggerScenarios":"Constructing ConfusionRuleEvaluator with a Language whose getRelevantLanguageModelRules returns null — i.e. the language module does not implement language model rules (most languages), or the rules cannot be created because no language model was wired in.","commonSituations":"Running confusion-rule evaluation for a language like a small-language module that has no ConfusionProbabilityRule implementation; passing a demo/test Language object instead of a full module language; forgetting to configure the language model directory so the relevant rules are not registered.","solutions":["Use a language that supports language model rules (e.g. English, German, French) — check the module implements getRelevantLanguageModelRules with a non-null list.","Configure the language model: pass the model directory via JLanguageTool.withLanguageModel(new LanguageModel(dir)) or the -lm command line option before constructing the evaluator.","Verify the language module jar is on the classpath so the full language implementation (not a stub) is loaded.","Guard the evaluator construction: check getRelevantLanguageModelRules != null beforehand and skip unsupported languages."],"exampleFix":"// before\nConfusionRuleEvaluator evaluator = new ConfusionRuleEvaluator(language, languageModel, caseSensitive, bothDirections);\n// after\nList<Rule> lmRules = language.getRelevantLanguageModelRules(JLanguageTool.getMessageBundle(), languageModel, null);\nif (lmRules == null) {\n  System.err.println(\"Skipping \" + language + \": no language model support\");\n  return;\n}\nConfusionRuleEvaluator evaluator = new ConfusionRuleEvaluator(language, languageModel, caseSensitive, bothDirections);","handlingStrategy":"try-catch","validationCode":"List<Rule> lmRules = language.getRelevantLanguageModelRules(JLanguageTool.getMessageBundle(), languageModel, null);\nif (lmRules == null || lmRules.isEmpty()) {\n  throw new UnsupportedOperationException(language + \" has no language model rules; pass a supported language and configure -lm\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  evaluator = new ConfusionRuleEvaluator(language, languageModel, caseSensitive, bothDirections);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"doesn't seem to support a language model\")) {\n    System.err.println(\"Skipping \" + language + \" (no LM support); supply -lm <modelDir> or a supported language\");\n  }\n}","preventionTips":["Only evaluate confusion rules for languages known to implement language model rules","Always configure the language model directory (JLanguageTool.withLanguageModel / -lm) before use","Check getRelevantLanguageModelRules() != null as a precondition in batch scripts","Keep the full language module jar on the classpath (no stub/demo Language objects)"],"tags":["java","nlp","language-model","configuration"],"backgroundTag":"feature-not-enabled","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"}