languagetool-org/languagetool · error · RuntimeException

Check failed on sentence

Error message

Check failed on sentence: ${StringUtils.abbreviate(sentence.getText(), 250)}

What it means

During SentenceSourceChecker.run, if checking an individual sentence throws any exception other than the control-flow DocumentLimitReachedException/ErrorLimitReachedException, it is wrapped in a RuntimeException quoting the first 250 characters of the sentence. Unless --skip-exceptions is set, one bad sentence aborts the whole run. The wrap exists to pinpoint which sentence broke the check.

Solutions

  1. Read the truncated sentence text in the message to find the offending content
  2. Re-run with --skip-exceptions to print stack traces and continue past bad sentences
  3. Fix or disable the specific rule that fails on that sentence
  4. Catch and skip in a wrapper around your own check pipeline

Example fix

// before
java ... -l en dump.xml
// after
java ... -l en --skip-exceptions dump.xml
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-screen sentences before the checker
if (sentence.getText() == null || sentence.getText().length() > 5000) {
  return; // skip pathological sentences
}

Try / catch

try {
  checker.run(dumpFiles);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Check failed on sentence")) {
    log.warn("Skipping run at sentence: " + e.getMessage(), e);
  } else throw e;
}

Prevention

When it happens

Trigger: LanguageTool rule code throws on pathological sentence text (regex stack overflow, null handling); the sentence source yields corrupt text; a plugin/rule bug triggered by specific content.

Common situations: StackOverflowError in regex-based rules on very long sentences; NPEs in custom rules; unusual Unicode in Wikipedia articles.


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

Appendix: source

Thrown at languagetool-wikipedia/src/main/java/org/languagetool/dev/dumpcheck/SentenceSourceChecker.java:278

          if (options.hasOption("print-correct")) {
            if (matches.getRuleMatches().size() == 0) {
              System.out.println(sentence.getText());
            }
          } else {
            resultHandler.handleResult(sentence, matches.getRuleMatches(), lang);
          }
          sentenceCount++;
          if (sentenceCount % 5000 == 0) {
            System.err.printf("%s sentences checked...\n", NumberFormat.getNumberInstance(Locale.US).format(sentenceCount));
          }
          ruleMatchCount += matches.getRuleMatches().size();
        } catch (DocumentLimitReachedException | ErrorLimitReachedException e) {
          throw e;
        } catch (Exception e) {
          if (options.hasOption("skip-exceptions")) {
            e.printStackTrace();
          } else {
            throw new RuntimeException("Check failed on sentence: " + StringUtils.abbreviate(sentence.getText(), 250), e);
          }
        }
      }
      ignoredCount = mixingSource.getIgnoredCount();
    } catch (DocumentLimitReachedException | ErrorLimitReachedException e) {
      System.out.println(getClass().getSimpleName() + ": " + e);
    } finally {
      lt.shutdown();
      if (resultHandler != null) {
        System.out.printf(lang + ": %d total matches\n", ruleMatchCount);
        System.out.printf(lang + ": %d total sentences considered\n", sentenceCount);
        float matchesPerSentence = (float)ruleMatchCount / sentenceCount;
        System.out.printf(Locale.ENGLISH, lang + ": ø%.2f rule matches per sentence\n", matchesPerSentence);
        System.out.printf(Locale.ENGLISH, lang + ": %d input lines ignored (e.g. not between %d and %d chars or at least %d tokens)\n", ignoredCount, 
          SentenceSource.MIN_SENTENCE_LENGTH, SentenceSource.MAX_SENTENCE_LENGTH, SentenceSource.MIN_SENTENCE_TOKEN_COUNT);
        if (options.hasOption("print-duration")) {
          System.out.println("The analysis took " + (System.currentTimeMillis() - startTime) + "ms");
        }

View on GitHub (pinned to 2e990059ce)