languagetool-org/languagetool · error · RuntimeException

Error analyzing sentence: '${sentence}' with rule ${rule.get

Error message

Error analyzing sentence: '${sentence}' with rule ${rule.getFullId()}

What it means

The catch-all branch of PatternRuleMatcher.match(): any non-IOException thrown while applying a pattern rule to a sentence is rethrown as RuntimeException('Error analyzing sentence: ...' with rule <fullId>). It names the failing rule so you can pinpoint the broken pattern definition. The cause is chained.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleMatcher.java:100

      doMatch(sentence, tokens, (tokenPositions, firstMatchToken, lastMatchToken, firstMarkerMatchToken, lastMarkerMatchToken) -> {
        RuleMatch ruleMatch = createRuleMatch(tokenPositions, tokens, firstMatchToken, lastMatchToken, firstMarkerMatchToken, lastMarkerMatchToken, sentence);
        if (ruleMatch != null) {
          ruleMatches.add(ruleMatch);
        }
      });
      RuleMatchFilter maxFilter = new RuleWithMaxFilter();
      List<RuleMatch> filteredMatches = maxFilter.filter(ruleMatches);
      /*if (slowMatchThreshold != null) {
        long runTime = System.currentTimeMillis() - startTime;
        if (runTime > slowMatchThreshold) {
          logger.warn("Slow match for rule " + rule.getFullId() + ": " + runTime + "ms, sentence len: " + sentence.getText().length() + " (threshold: " + slowMatchThreshold + "ms)");
        }
      }*/
      return filteredMatches.toArray(RuleMatch.EMPTY_ARRAY);
    } catch (IOException e) {
      throw new IOException("Error analyzing sentence: '" + sentence + "'", e);
    } catch (Exception e) {
      throw new RuntimeException("Error analyzing sentence: '" + sentence + "' with rule " + rule.getFullId(), e);
    } finally {
      if (key != null) {
        currentlyActiveRules.computeIfPresent(key, (k, v) -> v - 1 > 0 ? v - 1 : null);
      }
    }
  }

  @Override
  protected boolean testAllReadings(AnalyzedTokenReadings[] tokens, PatternTokenMatcher matcher, PatternTokenMatcher prevElement, int tokenNo, int firstMatchToken, int prevSkipNext) throws IOException {
    if (tokens[tokenNo].isImmunized()) return false;

    return super.testAllReadings(tokens, matcher, prevElement, tokenNo, firstMatchToken, prevSkipNext);
  }

  @Nullable
  private RuleMatch createRuleMatch(int[] tokenPositions,
                                    AnalyzedTokenReadings[] tokens, int firstMatchToken,
                                    int lastMatchToken, int firstMarkerMatchToken, int lastMarkerMatchToken,

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Read rule.getFullId() from the message and test that specific rule against the failing sentence.
  2. Inspect e.getCause() (e.g. PatternSyntaxException) and fix the rule's regex or token attributes.
  3. Validate the rule XML against LanguageTool's rule schema and simplify the pattern to isolate the offending token.
  4. Catch RuntimeException around getMatches per-rule and disable/report the broken rule at runtime.

Example fix

// before
<token regexp="[a-z+"/>
// after
<token regexp="[a-z]+"/>
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-compile all regexes used in rules at load time
for (String re : ruleRegexes) Pattern.compile(re); // throws PatternSyntaxException early

Try / catch

try {
  matches = matcher.match(sentence...);
} catch (RuntimeException e) {
  logger.error("Rule " + failingRuleId + " failed: " + e.getCause());
  disabledRules.add(failingRuleId);
}

Prevention

When it happens

Trigger: getMatches -> match() when rule matching throws any RuntimeException/Error, e.g. IndexOutOfBounds/ClassCast from a malformed pattern token, regex PatternSyntaxException at match time, or NullPointerException in a tokenizer interacting with the rule.

Common situations: Hand-written rule XML with invalid regex or wrong attribute combinations that only fails when applied to a particular sentence; version upgrade changing PatternToken semantics; negative-scope or case-sensitivity attributes misused in custom rules.

Related errors


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