{"record":{"id":"bbd3454764ce1a68","repo":"languagetool-org/languagetool","slug":"list-of-language-models-is-empty","errorCode":null,"errorMessage":"List of language models is empty","messagePattern":"List of language models is empty","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/languagemodel/MultiLanguageModel.java","lineNumber":35,"sourceCode":" * USA\n */\npackage org.languagetool.languagemodel;\n\nimport org.languagetool.rules.ngrams.Probability;\n\nimport java.util.List;\n\n/**\n * Combines the results of several {@link LanguageModel}s.\n * @since 3.2\n */\npublic class MultiLanguageModel implements LanguageModel {\n\n  private final List<LanguageModel> lms;\n\n  public MultiLanguageModel(List<LanguageModel> lms) {\n    if (lms.isEmpty()) {\n      throw new IllegalArgumentException(\"List of language models is empty\");\n    }\n    this.lms = lms;\n  }\n\n  @Override\n  public Probability getPseudoProbability(List<String> context) {\n    double prob = 0;\n    float coverage = 0;\n    long occurrences = 0;\n    for (LanguageModel lm : lms) {\n      Probability pProb = lm.getPseudoProbability(context);\n      //System.out.println(i + \". \" + pProb.getProb() + \" (\" + pProb.getCoverage() + \")\");\n      // TODO: decide what's the proper way to combine the probabilities\n      prob += pProb.getProb();\n      coverage += pProb.getCoverage();\n      occurrences += pProb.getOccurrences();\n    }\n    return new Probability(prob, coverage/lms.size(), occurrences);","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/languagemodel/MultiLanguageModel.java#L17-L53","documentation":"MultiLanguageModel's constructor requires at least one LanguageModel to combine; passing an empty list throws immediately. The class delegates probability lookups to the wrapped models, which is meaningless with none.","triggerScenarios":"new MultiLanguageModel(List.of()) or building the list programmatically (e.g. filtered by existing directories) such that no language models survive before construction.","commonSituations":"Conditional loading of several ngram models where every path was missing/invalid, producing an empty list that is then handed to the constructor.","solutions":["Pass a non-empty list of LanguageModel instances to the constructor.","Before constructing, check list size and fail early with a clear configuration error.","Fix the code that builds the list so model paths are validated/loaded before aggregation.","If models are optional, fall back to a null/absent LanguageModel instead of wrapping an empty list."],"exampleFix":"// before\nLanguageModel lm = new MultiLanguageModel(models.stream().filter(m -> exists(m)).collect(toList()));\n// after\nif (models.isEmpty()) throw new IllegalStateException(\"No ngram index configured\");\nLanguageModel lm = new MultiLanguageModel(models);","handlingStrategy":"validation","validationCode":"if (models == null || models.isEmpty())\n  throw new IllegalArgumentException(\"At least one LanguageModel is required\");\nLanguageModel lm = new MultiLanguageModel(models);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the model list before construction","Fail fast at configuration load time if ngram paths are missing"],"tags":["configuration","empty-list","language-model"],"backgroundTag":"invalid-argument-value","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"}