languagetool-org/languagetool · error · RuntimeException
IOException while initializing spellers
Error message
IOException while initializing spellers
What it means
MorfologikUkrainianSpellerRule.getSpeller1() lazily initializes the Morfologik spellers by calling isMisspelled("1") (which triggers initSpellers()); if that initialization throws an IOException it is wrapped in a RuntimeException. The speller dictionaries are compiled binary resources loaded from the classpath, so an IOException here means the dictionary data could not be read.
Source
Thrown at languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/MorfologikUkrainianSpellerRule.java:182
@Override
protected List<SuggestedReplacement> filterSuggestions(List<SuggestedReplacement> suggestions) {
suggestions = super.filterSuggestions(suggestions);
// do not suggest "кіно прокат, вело- прогулянка...":
suggestions.removeIf(item -> item.getReplacement().contains(" ") &&
DO_NOT_SUGGEST_SPACED_PATTERN.matcher(item.getReplacement()).matches() ||
item.getReplacement().contains("- "));
return suggestions;
}
// workaround to allow other rules generate spelling suggestions without invoking match()
MorfologikMultiSpeller getSpeller1() {
if( speller1 == null ) {
try {
// we can't call initSpellers() as it's private so we're calling method we can
isMisspelled("1");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return speller1;
}
@Override
protected boolean isLatinScript() {
return false;
}
}
View on GitHub (pinned to 2e990059ce)
Solutions
- Verify the Morfologik dictionary resources exist in the languagetool-language-modules/uk jar (unzip -l and look for *.dict).
- Rebuild/reinstall the language module so resources are packaged correctly.
- Run with the original (non-shaded) LanguageTool jars to avoid resource filtering stripping binary files.
- Inspect e.getCause() for the true failure (file corruption, permissions, classpath) and fix that.
- Pre-initialize spellers at startup in a guarded block so failures surface with clear diagnostics before serving traffic.
Example fix
// before
MorfologikMultiSpeller speller = rule.getSpeller1(); // throws RuntimeException on bad resource
// after
try {
MorfologikMultiSpeller speller = rule.getSpeller1();
} catch (RuntimeException e) {
LOG.error("Ukrainian speller init failed; check uk dictionary resources on classpath", e);
} Defensive patterns
Strategy: try-catch
Validate before calling
try (InputStream in = getClass().getResourceAsStream("/uk/ukrainian.dict")) {
if (in == null) throw new IllegalStateException("Ukrainian speller dictionary missing from classpath");
} Try / catch
try {
MorfologikMultiSpeller speller = rule.getSpeller1();
} catch (RuntimeException e) {
if (e.getCause() instanceof IOException) { LOG.error("Speller dictionary unreadable; disable spell check for uk", e); }
else throw e;
} Prevention
- Verify dictionary resources are packaged in the jar before deployment (unzip -l)
- Warm up speller initialization at startup, not on first user request
- Avoid shaded/filtered repackaging that strips or corrupts binary .dict files
- Keep artifact checksums pinned in CI to catch corrupted builds
When it happens
Trigger: First call to getSpeller1() (directly or via the first spell-check) when the Morfologik .dict/.info resources cannot be opened from the classpath, e.g. corrupted jar, missing resource, or I/O failure reading the binary dictionary.
Common situations: Incomplete/dependency-broken build where Ukrainian spelling resources weren't packaged; running from a shaded jar that excluded binary resources; running inside a container with a broken or partially extracted jar; classpath isolation (app servers) hiding resources.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Could not tag and disambiguate '<token>'
- Could not get rules of language <language>
- Could not load remote rules.
- Could not load coherency data from " + path
- Cannot load or parse input stream of '${filename}'
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/6d0dab31efb566ea.
Report an issue: GitHub.