{"record":{"id":"aaef2ee4f3347241","repo":"languagetool-org/languagetool","slug":"ioexception-while-synthesizing-suggestions-aaef2e","errorCode":null,"errorMessage":"IOException while synthesizing suggestions (його/її -> нього/неї)","messagePattern":"IOException while synthesizing suggestions \\(його/її -> нього/неї\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/TokenAgreementPrepNounRule.java","lineNumber":562,"sourceCode":"      msg += \". Можливо, тут потрібно присвійний займенник «їхній» або нормативна форма р.в. «них»?\";\n      try {\n        String newYihPostag = \"adj:p\" + requiredPostTagsRegEx + \".*\";\n        String[] synthesized = synthesizer.synthesize(new AnalyzedToken(\"їхній\", \"adj:m:v_naz.*:pron:pos\", \"їхній\"), newYihPostag, true);\n        suggestions.addAll( Arrays.asList(synthesized) );\n      } catch (IOException e) {\n        throw new RuntimeException(e);\n      }\n    }\n    else if( (tokenString.equals(\"його\") || tokenString.equals(\"її\")) && requiredPostTagsRegEx != null ) {\n      String repl = tokenString.equals(\"його\") ? \"нього\" : \"неї\";\n      msg += \". Можливо, тут потрібно присвійний займенник «\" + repl + \"»?\";\n      try {\n        String newYihPostag = \"adj:p\" + requiredPostTagsRegEx + \".*\";\n        String[] synthesized = synthesizer.synthesize(new AnalyzedToken(\"їхній\", \"adj:m:v_naz.*:pron:pos\", \"їхній\"), newYihPostag, true);\n        suggestions.addAll( Arrays.asList(synthesized) );\n        suggestions.add(repl);\n      } catch (IOException e) {\n        throw new RuntimeException(e);\n      }\n    }\n    else if( state.prepTokenReadings.getCleanToken().equalsIgnoreCase(\"о\") ) {\n      for(AnalyzedToken token: tokenReadings.getReadings()) {\n        if( PosTagHelper.hasPosTag(token, NOUN_ANIM_V_NAZ_PATTERN) ) {\n          msg += \". Можливо, тут «о» — це вигук і потрібно кличний відмінок?\";\n          try {\n            String newPostag = token.getPOSTag().replace(\"v_naz\", \"v_kly\");\n            String[] synthesized = synthesizer.synthesize(token, newPostag, false);\n            for (String string : synthesized) {\n              if( ! string.equals(token.getToken()) && ! suggestions.contains(string) ) {\n                suggestions.add( string );\n              }\n            }\n            break;\n          } catch (IOException e) {\n            throw new RuntimeException(e);\n          }","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/TokenAgreementPrepNounRule.java#L544-L580","documentation":"Another createRuleMatch() branch in TokenAgreementPrepNounRule handling «його»/«її» -> «него»/«неї» suggestions; after adding synthesized «їхній» forms and the replacement token, IOException from synthesize() is wrapped in RuntimeException. It indicates dictionary-synthesizer I/O failure, not a linguistic problem with the input text.","triggerScenarios":"Possessive pronoun agreement issue detected («його»/«її» with wrong-case noun); the rule synthesizes alternatives and the Morfologik dictionary read throws IOException.","commonSituations":"Corrupt or missing synthesizer dictionary in deployment; disk failures; jars damaged by build tooling (resource filtering of binary files).","solutions":["Resolve the root IOException in the cause chain before anything else.","Verify dictionary integrity in the deployed jar and redeploy a clean build if needed.","Catch the RuntimeException at the API/service boundary and return the match without inflected suggestions.","Add integration tests that run the rule over sample sentences to catch broken dictionaries in CI.","Avoid post-build jar mutations (repackaging, filtering) that can corrupt .dict resources."],"exampleFix":"// before\n} catch (IOException e) {\n  throw new RuntimeException(e);\n}\n// after\n} catch (IOException e) {\n  LOG.warn(\"pronoun suggestion synthesis failed\", e);\n  suggestions.add(repl); // still offer the direct replacement\n}","handlingStrategy":"try-catch","validationCode":"// ensure dictionary loads before processing text\nif (!isDictionaryHealthy()) {\n  throw new IllegalStateException(\"Ukrainian synthesizer dictionary unhealthy; aborting check run\");\n}","typeGuard":null,"tryCatchPattern":"try { matches = rule.match(tokens); }\ncatch (RuntimeException e) {\n  if (e.getCause() instanceof IOException) { LOG.warn(\"pronoun-replacement synthesis failed\", e); matches = Collections.emptyList(); }\n  else throw e;\n}","preventionTips":["Keep direct-replacement suggestions independent of synthesis so they survive synthesis failures","Add integration tests for «його»/«її» agreement paths","Verify jar integrity; rebuild on suspicion of corruption","Alert on repeated synthesis RuntimeExceptions in logs"],"tags":["io","synthesizer","pronoun","suggestions"],"backgroundTag":"file-read-failed","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}