{"record":{"id":"0f65f8b4f5f470dd","repo":"languagetool-org/languagetool","slug":"error-analyzing-sentence-sentence","errorCode":null,"errorMessage":"Error analyzing sentence: '${sentence}'","messagePattern":"Error analyzing sentence: '(.+?)'","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleMatcher.java","lineNumber":98,"sourceCode":"                                       ? sentence.getPreDisambigTokensWithoutWhitespace()\n                                       : sentence.getTokensWithoutWhitespace();\n      doMatch(sentence, tokens, (tokenPositions, firstMatchToken, lastMatchToken, firstMarkerMatchToken, lastMarkerMatchToken) -> {\n        RuleMatch ruleMatch = createRuleMatch(tokenPositions, tokens, firstMatchToken, lastMatchToken, firstMarkerMatchToken, lastMarkerMatchToken, sentence);\n        if (ruleMatch != null) {\n          ruleMatches.add(ruleMatch);\n        }\n      });\n      RuleMatchFilter maxFilter = new RuleWithMaxFilter();\n      List<RuleMatch> filteredMatches = maxFilter.filter(ruleMatches);\n      /*if (slowMatchThreshold != null) {\n        long runTime = System.currentTimeMillis() - startTime;\n        if (runTime > slowMatchThreshold) {\n          logger.warn(\"Slow match for rule \" + rule.getFullId() + \": \" + runTime + \"ms, sentence len: \" + sentence.getText().length() + \" (threshold: \" + slowMatchThreshold + \"ms)\");\n        }\n      }*/\n      return filteredMatches.toArray(RuleMatch.EMPTY_ARRAY);\n    } catch (IOException e) {\n      throw new IOException(\"Error analyzing sentence: '\" + sentence + \"'\", e);\n    } catch (Exception e) {\n      throw new RuntimeException(\"Error analyzing sentence: '\" + sentence + \"' with rule \" + rule.getFullId(), e);\n    } finally {\n      if (key != null) {\n        currentlyActiveRules.computeIfPresent(key, (k, v) -> v - 1 > 0 ? v - 1 : null);\n      }\n    }\n  }\n\n  @Override\n  protected boolean testAllReadings(AnalyzedTokenReadings[] tokens, PatternTokenMatcher matcher, PatternTokenMatcher prevElement, int tokenNo, int firstMatchToken, int prevSkipNext) throws IOException {\n    if (tokens[tokenNo].isImmunized()) return false;\n\n    return super.testAllReadings(tokens, matcher, prevElement, tokenNo, firstMatchToken, prevSkipNext);\n  }\n\n  @Nullable\n  private RuleMatch createRuleMatch(int[] tokenPositions,","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleMatcher.java#L80-L116","documentation":"PatternRuleMatcher.match() catches IOExceptions raised while matching a pattern rule against a sentence and rewraps them as IOException('Error analyzing sentence: ...'). This is the IOException-only branch; other exceptions get the RuntimeException variant (error 92). The cause chain holds the underlying rule-matching failure.","triggerScenarios":"getMatches -> match() when an IOException occurs inside the per-rule matching loop, e.g. a token/element check needs an I/O-backed resource that fails while processing the given sentence.","commonSituations":"Custom rules loading resources lazily (disambiguation/regex data) and hitting a missing/corrupt resource mid-match; temp files deleted; underlying reader throwing on unusual characters in the sentence.","solutions":["Inspect e.getCause() for the underlying IOException source and fix that resource/IO issue.","Verify any resources referenced by the rule (regex files, binary rule caches) are present and readable.","Wrap getMatches in try-catch and degrade gracefully (skip the rule) instead of aborting the whole check.","Re-encode the input sentence text as UTF-8 before passing it to the analyzer."],"exampleFix":"// before\nList<RuleMatch> m = matcher.match(analyzedText);\n// after\ntry {\n  List<RuleMatch> m = matcher.match(analyzedText);\n} catch (IOException e) {\n  logger.warn(\"Rule failed on sentence: \" + e.getCause());\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  matches = matcher.match(sentence...);\n} catch (IOException e) {\n  logger.warn(\"Sentence skipped, cause: \" + e.getCause());\n}","preventionTips":["Package all resources rules reference lazily (regex/data files) and verify at startup.","Normalize sentence text encoding to UTF-8 before analysis.","Inspect causes rather than retrying blindly.","Test custom rules against edge-case sentences before deployment."],"tags":["io","sentence-analysis","java"],"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-14T00:17:10.932Z"}