{"record":{"id":"b33117fd92cb8870","repo":"languagetool-org/languagetool","slug":"ioexception-while-synthesizing-suggestions-voca","errorCode":null,"errorMessage":"IOException while synthesizing suggestions (о vocative)","messagePattern":"IOException while synthesizing suggestions \\(о vocative\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/TokenAgreementPrepNounRule.java","lineNumber":579,"sourceCode":"      } 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          }\n        }\n      }\n    }\n    else if( PosTagHelper.hasPosTagStart(tokens[i-1], \"adv\")) {\n      String mergedToken = state.prepTokenReadings.getCleanToken() + tokens[i-1].getCleanToken();\n      List<AnalyzedTokenReadings> mergedTagged = ukrainian.getTagger().tag(Arrays.asList(mergedToken));\n      if( PosTagHelper.hasPosTagStart(mergedTagged.get(0), \"adv\") ) {\n        msg += \". Можливо, прийменник і прислівник мають бути одним словом?\";\n//        suggestions.add(mergedToken);\n      }\n      \n    }\n\n    RuleMatch potentialRuleMatch = new RuleMatch(this, sentence, tokenReadings.getStartPos(), tokenReadings.getEndPos(), msg, getShort());\n\n    potentialRuleMatch.setSuggestedReplacements(suggestions);\n","sourceCodeStart":561,"sourceCodeEnd":597,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/TokenAgreementPrepNounRule.java#L561-L597","documentation":"In the vocative («о» + name) branch of TokenAgreementPrepNounRule.createRuleMatch(), the rule synthesizes vocative forms of the following token and wraps IOException in RuntimeException. The break-in-loop catch pattern means the first synthesis failure aborts suggestion generation for the whole match.","triggerScenarios":"Token «о» precedes a noun matching the animate nominative pattern; the rule synthesizes vocative inflections and the synthesizer's dictionary read throws IOException.","commonSituations":"Dictionary resource corruption, unreadable files (permissions), or storage-level I/O failures in the deployment environment; broken language-module builds.","solutions":["Inspect the wrapped IOException (getCause()) to find the failing resource or disk issue.","Verify/repair the Ukrainian synthesizer dictionary in the deployed artifact.","Move synthesis into a helper that returns an empty array on IOException so the rule can still flag the vocative issue without inflected forms.","Check file permissions and disk health on the host running LanguageTool.","Add a CI test exercising the «о» vocative path to detect dictionary problems early."],"exampleFix":"// before\n} catch (IOException e) {\n  throw new RuntimeException(e);\n}\n// after\n} catch (IOException e) {\n  LOG.warn(\"vocative synthesis failed\", e);\n  break; // skip synthesized vocative suggestions for this token\n}","handlingStrategy":"try-catch","validationCode":"try {\n  synthesizer.synthesize(new AnalyzedToken(\"Іване\", \"noun:anim:v_kly\", \"Іван\"), \"noun:anim:v_naz\", true);\n} catch (IOException e) { LOG.error(\"Vocative synthesis unavailable\", e); }","typeGuard":null,"tryCatchPattern":"try { matches = rule.match(tokens); }\ncatch (RuntimeException e) {\n  if (e.getCause() instanceof IOException) { LOG.warn(\"vocative synthesis failed\", e); /* flag issue without suggestions */ }\n  else throw e;\n}","preventionTips":["Check file permissions and disk health where dictionaries live","Test the «о» + name vocative path in CI","Avoid per-token fatal catches: skip suggestion generation instead","Validate dictionary resources exist in the runtime image"],"tags":["io","synthesizer","vocative","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"}