languagetool-org/languagetool · error · RuntimeException
IOException while synthesizing suggestions (їх -> їхній)
Error message
IOException while synthesizing suggestions (їх -> їхній)
What it means
Same createRuleMatch() flow in TokenAgreementPrepNounRule, but for the special-case suggestion «їх» -> «їхній»: synthesize() is called with a synthetic AnalyzedToken("їхній", ...) and IOException is wrapped in RuntimeException. The failure means the dictionary synthesizer could not be read while building this possessive-pronoun suggestion.
Source
Thrown at languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/TokenAgreementPrepNounRule.java:550
state.prepTokenReadings.getToken(), String.join(", ", reqVidminkyNames), String.join(", ", foundVidminkyNames));
if( state.ziZnaRemoved ) {
msg += ". Але з.в. вимагається у випадках порівнянн предметів.";
}
if( state.posTagsToFind.contains("v_rod")
&& tokens[i].getToken().matches(".*[ую]")
&& PosTagHelper.hasPosTag(tokenReadings.getReadings(), Pattern.compile("noun.*?:m:v_dav.*")) ) {
msg += CaseGovernmentHelper.USED_U_INSTEAD_OF_A_MSG;
}
else if( tokenString.equals("їх") && requiredPostTagsRegEx != null ) {
msg += ". Можливо, тут потрібно присвійний займенник «їхній» або нормативна форма р.в. «них»?";
try {
String newYihPostag = "adj:p" + requiredPostTagsRegEx + ".*";
String[] synthesized = synthesizer.synthesize(new AnalyzedToken("їхній", "adj:m:v_naz.*:pron:pos", "їхній"), newYihPostag, true);
suggestions.addAll( Arrays.asList(synthesized) );
} catch (IOException e) {
throw new RuntimeException(e);
}
}
else if( (tokenString.equals("його") || tokenString.equals("її")) && requiredPostTagsRegEx != null ) {
String repl = tokenString.equals("його") ? "нього" : "неї";
msg += ". Можливо, тут потрібно присвійний займенник «" + repl + "»?";
try {
String newYihPostag = "adj:p" + requiredPostTagsRegEx + ".*";
String[] synthesized = synthesizer.synthesize(new AnalyzedToken("їхній", "adj:m:v_naz.*:pron:pos", "їхній"), newYihPostag, true);
suggestions.addAll( Arrays.asList(synthesized) );
suggestions.add(repl);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
else if( state.prepTokenReadings.getCleanToken().equalsIgnoreCase("о") ) {
for(AnalyzedToken token: tokenReadings.getReadings()) {
if( PosTagHelper.hasPosTag(token, NOUN_ANIM_V_NAZ_PATTERN) ) {
msg += ". Можливо, тут «о» — це вигук і потрібно кличний відмінок?";View on GitHub (pinned to 2e990059ce)
Solutions
- Fix the underlying IOException found in the cause chain (resource, disk, permissions).
- Rebuild/verify the uk dictionary resources in the artifact.
- Degrade gracefully: keep the message but skip synthesized suggestions when synthesis fails.
- Run a startup smoke test of the synthesizer to catch dictionary problems before serving requests.
- Monitor for repeated RuntimeExceptions with this stack to detect environment-level dictionary corruption.
Example fix
// before
String[] synthesized = synthesizer.synthesize(new AnalyzedToken("їхній", "adj:m:v_naz.*:pron:pos", "їхній"), newYihPostag, true);
// after
String[] synthesized;
try {
synthesized = synthesizer.synthesize(new AnalyzedToken("їхній", "adj:m:v_naz.*:pron:pos", "їхній"), newYihPostag, true);
} catch (IOException e) {
LOG.warn("synthesis for їхній failed", e);
synthesized = new String[0];
} Defensive patterns
Strategy: try-catch
Validate before calling
try {
synthesizer.synthesize(new AnalyzedToken("їхній", "adj:m:v_naz.*:pron:pos", "їхній"), "adj:p:v_naz", true);
} catch (IOException e) { throw new IllegalStateException("Cannot synthesize їхній forms", e); } Try / catch
try { matchResult = rule.match(tokens); }
catch (RuntimeException e) {
if (e.getCause() instanceof IOException) { LOG.warn("їхній synthesis failed; keep message, drop suggestions", e); }
else throw e;
} Prevention
- Include the special-case pronoun paths in CI smoke tests
- Verify dictionary integrity on deploy
- Degrade to suggestion-less matches on synthesis I/O failure
- Track cause-chain IOExceptions to catch environment degradation
When it happens
Trigger: Text contains «їх» where an adjectival possessive or normative genitive is expected; the rule synthesizes forms of «їхній» and the synthesizer throws IOException.
Common situations: Same root causes as other synthesis failures: damaged Morfologik dictionaries, storage I/O errors, broken deployment artifacts.
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 (його/її -> нього
- IOException while synthesizing suggestions (adj-noun agreeme
- IOException while synthesizing suggestions (prep-noun agreem
- 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/fb76ecca94cc7463.
Report an issue: GitHub.