{"record":{"id":"0c954793e83bf11a","repo":"languagetool-org/languagetool","slug":"cannot-synthesize-token-exception","errorCode":null,"errorMessage":"Cannot synthesize <token><exception>","messagePattern":"Cannot synthesize <token><exception>","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"languagetool-language-modules/pt/src/main/java/org/languagetool/rules/pt/RegularIrregularParticipleFilter.java","lineNumber":74,"sourceCode":"      for (AnalyzedToken at : atr) {\n        if (at.getPOSTag() != null && at.getPOSTag().startsWith(\"VMP\")) {\n          selectedAT = at;\n          desiredPostag = at.getPOSTag();\n        }\n      }\n      // assente SC assentado SM\n      if (desiredPostag.endsWith(\"C\")) {\n        desiredPostag = desiredPostag.substring(0,desiredPostag.length() - 1) + \"[MC]\";\n      } else {\n        desiredPostag = desiredPostag.substring(0,desiredPostag.length() - 1) \n            + \"[\"+ desiredPostag.substring(desiredPostag.length() - 1) + \"C]\";\n      }\n      \n      String[] participles;\n      try {\n        participles = synth.synthesize(selectedAT, desiredPostag, true);\n      } catch (IOException e) {\n        throw new IOException(\"Cannot synthesize \" + selectedAT.toString() + e);\n      }\n      if (participles != null && participles.length > 1) {\n        if (direction.equalsIgnoreCase(\"RegularToIrregular\") && isRegular(atr.getToken())) {\n          if (!isRegular(participles[0])) {\n            replacement = participles[0];\n          } else if (!isRegular(participles[1])) {\n            replacement = participles[1];\n          }\n        } else if (direction.equalsIgnoreCase(\"IrregularToRegular\") && !isRegular(atr.getToken())) {\n          if (isRegular(participles[0])) {\n            replacement = participles[0];\n          } else if (isRegular(participles[1])) {\n            replacement = participles[1];\n          }\n        }\n        if (replacement != null) {\n          String message = match.getMessage();\n          RuleMatch ruleMatch = new RuleMatch(match.getRule(), match.getSentence(), match.getFromPos(),","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-language-modules/pt/src/main/java/org/languagetool/rules/pt/RegularIrregularParticipleFilter.java#L56-L92","documentation":"RegularIrregularParticipleFilter.acceptRuleMatch synthesizes the desired participle form of a verb using the Portuguese synthesizer. If synthesize(AnalyzedToken, postag, true) throws an IOException (typically the synthesizer dictionary could not be read or the requested form cannot be generated), it is rethrown as this IOException('Cannot synthesize <token><exception>').","triggerScenarios":"Calling synthesize on an AnalyzedToken with a POS tag for which the Portuguese synthesis dictionary has no forms, or when the synthesis dictionary resource fails to load (IOException from the binary dictionary reader).","commonSituations":"Rule pair RegularToIrregular/IrregularToRegular applied to verbs missing from the synthesizer's exception dictionary; corrupted/missing pt dictionary in a custom build; unexpected POS tags produced upstream by the tagger.","solutions":["Inspect the concatenated exception in the message to distinguish a missing-form vs dictionary-I/O problem; rebuild the pt module if resources are missing","Extend the synthesizer's exception data (irregular participle list) for the verb/token shown in the message","Guard the filter: if synthesize returns no usable forms, skip the match instead of propagating (or catch IOException and return the unmodified match)"],"exampleFix":"// before\ntry {\n  participles = synth.synthesize(selectedAT, desiredPostag, true);\n} catch (IOException e) {\n  throw new IOException(\"Cannot synthesize \" + selectedAT.toString() + e);\n}\n// after\ntry {\n  participles = synth.synthesize(selectedAT, desiredPostag, true);\n} catch (IOException e) {\n  return Collections.singletonList(match); // skip suggestion instead of failing the rule\n}","handlingStrategy":"fallback","validationCode":"// confirm the verb has irregular participle data before applying the rule:\ntry {\n  AnalyzedToken at = new AnalyzedToken(verb, postag, lemma);\n  String[] forms = synth.synthesize(at, desiredPostag, true);\n  if (forms == null || forms.length == 0) skip = true; // no synthesized participle\n} catch (IOException e) { skip = true; }","typeGuard":null,"tryCatchPattern":"try { return super.acceptRuleMatch(match, propositions, args); } catch (IOException e) { log.warn(\"Participle synthesis failed: {}\", e.getMessage()); return Collections.singletonList(match); /* leave text unchanged */ }","preventionTips":["Prefer skipping the suggestion over propagating synthesis failures in grammar filters","Keep the pt synthesizer/exception dictionaries up to date in your build","Log the token and POS tag from the message to extend irregular-verb data for recurring cases"],"tags":["java","nlp","synthesizer","io","grammar-rules"],"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"}