{"record":{"id":"68acff6639647609","repo":"languagetool-org/languagetool","slug":"found-more-than-one-spell-rule","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/UnknownWordFinder.java","lineNumber":64,"sourceCode":"  private final Set<String> unknownTag = new HashSet<>();\n\n  private void run(File dir, JLanguageTool lt) throws IOException {\n    SpellingCheckRule spellerRule = getSpellingCheckRule(lt);\n    Tagger tagger = lt.getLanguage().getTagger();\n    List<Path> files = Files.walk(dir.toPath()).filter(Files::isRegularFile).collect(Collectors.toList());\n    for (Path file : files) {\n      handle(file, lt, spellerRule, tagger);\n    }\n    printResult(unknownWords);\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, JLanguageTool lt, SpellingCheckRule rule, Tagger tagger) throws IOException {\n    String text = null;\n    if (f.toString().toLowerCase().endsWith(\".txt\")) {\n      List<String> lines = Files.readAllLines(f);\n      text = String.join(\" \", lines);\n    } else if (f.toString().toLowerCase().endsWith(\".rtf\")) {\n      text = getTextFromRtf(f);\n    } else {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-dev/src/main/java/org/languagetool/dev/UnknownWordFinder.java#L46-L82","documentation":"UnknownWordFinder.getSpellingCheckRule scans all active rules of a JLanguageTool instance and requires exactly one dictionary-based spelling rule. If a second one is found it throws a RuntimeException, since the tool needs a single unambiguous speller rule to configure.","triggerScenarios":"Running UnknownWordFinder against a language whose configuration activates two or more dictionary-based spelling rules (e.g. both a hunspell and a simple spelling rule active).","commonSituations":"Languages with multiple spelling rules enabled by default; enabling extra spelling rules in custom configuration; recent rule additions changing the active-rule set.","solutions":["Deactivate all but one dictionary-based spelling rule before passing the JLanguageTool to the finder (lt.disableRule(...) for the extras)","Run the finder for a language that has a single active speller rule","Patch the script to collect and use the first (or a chosen) speller rule instead of failing"],"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 UnknownWordFinder(...).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":["Deactivate non-primary spelling rules before analysis tools run","Verify active-rule counts per language in tests","Keep language configs with a single dictionary-based speller"],"tags":["spelling","rules","dev-tool"],"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"}