{"record":{"id":"afe9f228af1470c6","repo":"languagetool-org/languagetool","slug":"found-more-than-one-spell-rule-afe9f2","errorCode":null,"errorMessage":"Found more than one spell rule: ","messagePattern":"Found more than one spell rule: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"languagetool-dev/src/main/java/org/languagetool/dev/UnknownWordFinderForCsv.java","lineNumber":52,"sourceCode":" * Print words from CSV that are unknown to the spell checker, sorted by number of occurrences.\n */\npublic class UnknownWordFinderForCsv {\n\n  private void run(File dir, JLanguageTool lt) throws IOException {\n    SpellingCheckRule spellerRule = getSpellingCheckRule(lt);\n    List<Path> files = Files.walk(dir.toPath()).filter(Files::isRegularFile).collect(Collectors.toList());\n    for (Path file : files) {\n      handle(file, spellerRule);\n    }\n  }\n\n  @NotNull\n  private SpellingCheckRule getSpellingCheckRule(JLanguageTool lt) {\n    SpellingCheckRule spellerRule = null;\n    for (Rule rule : lt.getAllActiveRules()) {\n      if (rule.isDictionaryBasedSpellingRule()) {\n        if (spellerRule != null) {\n          throw new RuntimeException(\"Found more than one spell rule: \" + rule + \", \" + spellerRule);\n        }\n        spellerRule = (SpellingCheckRule) rule;\n      }\n    }\n    if (spellerRule == null) {\n      throw new RuntimeException(\"No speller rule found for \" + lt.getLanguage());\n    }\n    return spellerRule;\n  }\n\n  private void handle(Path f, SpellingCheckRule rule) throws IOException {\n    int i = 0;\n    if (f.toString().toLowerCase().endsWith(\".csv\")) {\n      List<String> lines = Files.readAllLines(f);\n      for (String line : lines) {\n        String[] parts = line.split(\",\");\n        String word = parts[0].replace(\"\\\"\", \"\");\n        if (rule.isMisspelled(word)) {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-dev/src/main/java/org/languagetool/dev/UnknownWordFinderForCsv.java#L34-L70","documentation":"UnknownWordFinderForCsv.getSpellingCheckRule mirrors UnknownWordFinder: it expects exactly one dictionary-based spelling rule among active rules and throws a RuntimeException when a second one is encountered, because the CSV variant also needs a single well-defined speller rule.","triggerScenarios":"Running UnknownWordFinderForCsv with a JLanguageTool whose active rule set contains two or more dictionary-based spelling rules.","commonSituations":"Languages with multiple active spell checkers; extra spelling rules enabled via custom config; behavior changes after adding new spelling rules to a language module.","solutions":["Disable all but one dictionary-based spelling rule before calling getSpellingCheckRule","Run the tool for a language with a single active speller rule","Modify the script to tolerate multiple speller rules by picking one explicitly"],"exampleFix":"// before\nSpellingCheckRule rule = getSpellingCheckRule(lt);\n// after\nlt.getAllActiveRules().stream().filter(Rule::isDictionaryBasedSpellingRule).skip(1).forEach(r -> lt.disableRule(r.getId()));\nSpellingCheckRule rule = getSpellingCheckRule(lt);","handlingStrategy":"validation","validationCode":"long n = lt.getAllActiveRules().stream().filter(Rule::isDictionaryBasedSpellingRule).count();\nif (n != 1) throw new IllegalStateException(\"Expected exactly 1 spelling rule, got \" + n);","typeGuard":null,"tryCatchPattern":"try { new UnknownWordFinderForCsv(...).run(); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Found more than one spell rule\")) { System.err.println(\"Disable extra spelling rules for this language\"); } }","preventionTips":["Keep one active dictionary-based spelling rule per language","Disable secondary speller rules before CSV scans","Assert speller-rule counts in configuration tests"],"tags":["spelling","rules","csv"],"backgroundTag":"internal-invariant-violation","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}