languagetool-org/languagetool · error · RuntimeException
IOException while synthesizing suggestions (prep-noun agreem
Error message
IOException while synthesizing suggestions (prep-noun agreement)
What it means
In TokenAgreementPrepNounRule.createRuleMatch() (invoked via potentialRuleMatch), preposition-noun agreement suggestions are produced by synthesizer.synthesize(analyzedToken, posTag, true); IOException is wrapped in RuntimeException. This means the Morfologik synthesizer failed to read its dictionary while generating inflected noun/adjective forms.
Source
Thrown at languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/TokenAgreementPrepNounRule.java:500
String requiredPostTagsRegExToApply = requiredPostTagsRegEx;
Matcher matcher = REQ_ANIM_INANIM_PATTERN.matcher(oldPosTag);
if( matcher.find() ) {
requiredPostTagsRegExToApply += matcher.group(0);
}
else {
requiredPostTagsRegExToApply += "(?:" + reqAnimInanimRegex + ")?";
}
String posTag = oldPosTag.replaceFirst(":v_[a-z]+", requiredPostTagsRegExToApply);
try {
String[] synthesized = synthesizer.synthesize(analyzedToken, posTag, true);
suggestions.addAll( Arrays.asList(synthesized) );
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if( suggestions.size() > 0 ) { // remove duplicates
suggestions = new ArrayList<>(new LinkedHashSet<>(suggestions));
}
List<String> reqVidminkyNames = new ArrayList<>();
for (String vidm: state.posTagsToFind) {
reqVidminkyNames.add(PosTagHelper.VIDMINKY_MAP.get(vidm));
}
List<String> foundVidminkyNames = new ArrayList<>();
for (AnalyzedToken token: tokenReadings) {
String posTag2 = token.getPOSTag();
if( posTag2 != null && posTag2.contains(VIDMINOK_SUBSTR) ) {
String vidmName = PosTagHelper.VIDMINKY_MAP.get(posTag2.replaceFirst("^.*"+VIDMINOK_REGEX+".*$", "$1"));
if( foundVidminkyNames.contains(vidmName) ) {View on GitHub (pinned to 2e990059ce)
Solutions
- Read e.getCause() to identify the underlying resource/I/O problem.
- Verify and if needed rebuild the Ukrainian dictionary resources in the deployed jar.
- Add a startup self-test that synthesizes a known token/posTag pair to fail fast on broken dictionaries.
- Catch the RuntimeException at the service boundary and return the disagreement without suggestions.
- Ensure your packaging/shading config excludes binary resources from filtering.
Example fix
// before
String[] synthesized = synthesizer.synthesize(analyzedToken, posTag, true);
// after
String[] synthesized;
try {
synthesized = synthesizer.synthesize(analyzedToken, posTag, true);
} catch (IOException e) {
LOG.warn("synthesis failed, no suggestions will be added", e);
synthesized = new String[0];
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check synthesizer availability
Objects.requireNonNull(synthesizer, "synthesizer not initialized");
if (!dictionaryLoaded) throw new IllegalStateException("Ukrainian synthesizer dictionary not loaded"); Try / catch
try { matches = rule.match(tokens); }
catch (RuntimeException e) {
if (e.getCause() instanceof IOException) { LOG.warn("prep-noun synthesis failed", e); /* return match without suggestions */ }
else throw e;
} Prevention
- Startup self-test: synthesize a known token/posTag pair
- Exclude binary dictionaries from build resource filtering
- Watch disk/permission errors on hosts running LanguageTool
- Return empty suggestions instead of crashing the whole check request
When it happens
Trigger: Preposition-noun case disagreement found in text, rule calls synthesize() to build correct inflected forms, and the dictionary lookup raises IOException (unreadable/corrupt dictionary resource or storage error).
Common situations: Corrupted uk language dictionaries in deployment; disk or volume errors; jars damaged by aggressive build filtering or repackaging; memory-constrained environments failing during dictionary load.
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
- IOException while synthesizing suggestions (adj-noun agreeme
- IOException while synthesizing suggestions (їх -> їхній)
- IOException while synthesizing suggestions (його/її -> нього
- IOException while synthesizing suggestions (о vocative)
- throw new RuntimeException(e)
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/84dbf1cda6f58d09.
Report an issue: GitHub.