languagetool-org/languagetool · error
Found more than one spell rule:
Error message
Found more than one spell rule:
What it means
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.
Source
Thrown at languagetool-dev/src/main/java/org/languagetool/dev/UnknownWordFinder.java:64
private final Set<String> unknownTag = new HashSet<>();
private void run(File dir, JLanguageTool lt) throws IOException {
SpellingCheckRule spellerRule = getSpellingCheckRule(lt);
Tagger tagger = lt.getLanguage().getTagger();
List<Path> files = Files.walk(dir.toPath()).filter(Files::isRegularFile).collect(Collectors.toList());
for (Path file : files) {
handle(file, lt, spellerRule, tagger);
}
printResult(unknownWords);
}
@NotNull
private SpellingCheckRule getSpellingCheckRule(JLanguageTool lt) {
SpellingCheckRule spellerRule = null;
for (Rule rule : lt.getAllActiveRules()) {
if (rule.isDictionaryBasedSpellingRule()) {
if (spellerRule != null) {
throw new RuntimeException("Found more than one spell rule: " + rule + ", " + spellerRule);
}
spellerRule = (SpellingCheckRule) rule;
}
}
if (spellerRule == null) {
throw new RuntimeException("No speller rule found for " + lt.getLanguage());
}
return spellerRule;
}
private void handle(Path f, JLanguageTool lt, SpellingCheckRule rule, Tagger tagger) throws IOException {
String text = null;
if (f.toString().toLowerCase().endsWith(".txt")) {
List<String> lines = Files.readAllLines(f);
text = String.join(" ", lines);
} else if (f.toString().toLowerCase().endsWith(".rtf")) {
text = getTextFromRtf(f);
} else {View on GitHub (pinned to 2e990059ce)
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
Example fix
// before SpellingCheckRule rule = getSpellingCheckRule(lt); // after lt.getAllActiveRules().stream().filter(Rule::isDictionaryBasedSpellingRule).skip(1).forEach(r -> lt.disableRule(r.getId())); SpellingCheckRule rule = getSpellingCheckRule(lt);
Defensive patterns
Strategy: validation
Validate before calling
long n = lt.getAllActiveRules().stream().filter(Rule::isDictionaryBasedSpellingRule).count();
if (n != 1) throw new IllegalStateException("Expected exactly 1 spelling rule, got " + n); Try / catch
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"); } } Prevention
- 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
When it happens
Trigger: 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).
Common situations: Languages with multiple spelling rules enabled by default; enabling extra spelling rules in custom configuration; recent rule additions changing the active-rule set.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- No speller rule found for
- Found more than one spell rule:
- No speller rule found for
- No rules are active. Please make sure your rule ids (<option
- Could not activate rules
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/68acff6639647609.
Report an issue: GitHub.