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

  1. Read e.getCause() to identify the underlying resource/I/O problem.
  2. Verify and if needed rebuild the Ukrainian dictionary resources in the deployed jar.
  3. Add a startup self-test that synthesizes a known token/posTag pair to fail fast on broken dictionaries.
  4. Catch the RuntimeException at the service boundary and return the disagreement without suggestions.
  5. 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

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


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/84dbf1cda6f58d09. Report an issue: GitHub.