languagetool-org/languagetool · error · IllegalArgumentException

No end error marker ( + errorMarker.getEndMarker() + ) found

Error message

No end error marker ( + errorMarker.getEndMarker() + ) found in text with correction

What it means

Same validation as the start marker: the private RuleMatchApplication constructor requires the ErrorMarker's end marker to be present in textWithCorrection, otherwise an IllegalArgumentException is thrown. Without the end marker the corrected-region end offset cannot be computed.

Source

Thrown at languagetool-wikipedia/src/main/java/org/languagetool/dev/wikipedia/RuleMatchApplication.java:47

  private final String text;
  private final String textWithCorrection;
  private final ErrorMarker errorMarker;
  private final boolean hasRealReplacement;

  static RuleMatchApplication forMatchWithReplacement(RuleMatch ruleMatch, String text, String textWithCorrection, ErrorMarker errorMarker) {
    return new RuleMatchApplication(ruleMatch, text, textWithCorrection, errorMarker, true);
  }

  static RuleMatchApplication forMatchWithoutReplacement(RuleMatch ruleMatch, String text, String textWithCorrection, ErrorMarker errorMarker) {
    return new RuleMatchApplication(ruleMatch, text, textWithCorrection, errorMarker, false);
  }

  private RuleMatchApplication(RuleMatch ruleMatch, String text, String textWithCorrection, ErrorMarker errorMarker, boolean hasRealReplacement) {
    if (!textWithCorrection.contains(errorMarker.getStartMarker())) {
      throw new IllegalArgumentException("No start error marker (" + errorMarker.getStartMarker() + ") found in text with correction");
    }
    if (!textWithCorrection.contains(errorMarker.getEndMarker())) {
      throw new IllegalArgumentException("No end error marker (" + errorMarker.getEndMarker() + ") found in text with correction");
    }
    this.ruleMatch = ruleMatch;
    this.text = text;
    this.textWithCorrection = textWithCorrection;
    this.errorMarker = errorMarker;
    this.hasRealReplacement = hasRealReplacement;
  }

  public String getOriginalErrorContext(int contextSize) {
    return getContext(text, contextSize);
  }

  public String getCorrectedErrorContext(int contextSize) {
    return getContext(textWithCorrection, contextSize);
  }

  private String getContext(String text, int contextSize) {
    int errorStart = textWithCorrection.indexOf(errorMarker.getStartMarker());

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Ensure both start and end markers are preserved in textWithCorrection
  2. Check the correction logic doesn't strip or consume the closing marker
  3. Validate text completeness (no truncation) before constructing RuleMatchApplication
  4. Use consistent ErrorMarker constants for generation and validation

Example fix

// before
corrected = text.replace(start, start); // loses end marker pairing
// after
corrected = textWithMarkers; // contains "<err>...</err>" both markers intact
Defensive patterns

Strategy: validation

Validate before calling

if (!textWithCorrection.contains(errorMarker.getEndMarker())) {
  throw new IllegalStateException("correction text lost end marker");
}

Try / catch

try {
  app = RuleMatchApplication.forMatchWithReplacement(match, text, corrected, marker, true);
} catch (IllegalArgumentException e) {
  LOG.error("end marker missing in corrected text", e);
}

Prevention

When it happens

Trigger: textWithCorrection contains the start marker but not the end marker — truncated text, an unbalanced marker (start inserted without closing), or markers removed between generation and this call.

Common situations: Regex/string replacement that consumed the closing marker; text truncated at a boundary cutting off the end tag; mismatched ErrorMarker constants.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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