languagetool-org/languagetool · error · RuntimeException

JSON item ${elem} doesn't contain required property '${prope

Error message

JSON item ${elem} doesn't contain required property '${propertyName}'

What it means

RemoteLanguageTool.getRequired extracts a mandatory property from a JSON response item and throws a RuntimeException when the key is absent (null). It is the client's contract check that the server response contains every field the Java model requires; callers include offset(), errorLength(), contextOffset() and getRequiredString().

Source

Thrown at languagetool-http-client/src/main/java/org/languagetool/remote/RemoteLanguageTool.java:334

    remoteMatch.setLocQualityIssueType(getOrNull(rule, "issueType"));
    List<String> urls = getValueList(rule, "urls");
    if (urls.size() > 0) {
      remoteMatch.setUrl(urls.get(0));
    }
    Map<String, Object> category = (Map<String, Object>) rule.get("category");
    remoteMatch.setCategory(getOrNull(category, "name"));
    remoteMatch.setCategoryId(getOrNull(category, "id"));

    remoteMatch.setReplacements(getValueList(match, "replacements"));
    return remoteMatch;
  }

  private Object getRequired(Map<String, Object> elem, String propertyName) {
    Object val = elem.get(propertyName);
    if (val != null) {
      return val;
    }
    throw new RuntimeException("JSON item " + elem + " doesn't contain required property '" + propertyName + "'");
  }

  private String getRequiredString(Map<String, Object> elem, String propertyName) {
    return (String) getRequired(elem, propertyName);
  }

  private String getOrNull(Map<String, Object> elem, String propertyName) {
    Object val = elem.get(propertyName);
    if (val != null) {
      return (String) val;
    }
    return null;
  }

  private List<String> getValueList(Map<String, Object> match, String propertyName) {
    List<Object> matches = (List<Object>) match.get(propertyName);
    List<String> l = new ArrayList<>();
    if (matches != null) {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Log the raw JSON response and compare it with the expected /v2/check schema (offset, length, context, etc.)
  2. Align client and server versions of LanguageTool
  3. Check the URL actually points at a LanguageTool API endpoint, not a login/error page returning JSON
  4. If a field is legitimately optional in your setup, adjust the client model or add a default

Example fix

// before
String base = getRequiredString(map, "context"); // throws if absent
// after
if (map.containsKey("context")) {
  String base = getRequiredString(map, "context");
} else {
  log.warn("missing 'context' in response item: " + map);
}
Defensive patterns

Strategy: validation

Validate before calling

Map<String, Object> match = ...; // parsed JSON item
for (String req : List.of("offset", "length", "context", "message")) {
  if (!match.containsKey(req)) throw new IllegalStateException("missing field: " + req);
}

Type guard

static boolean hasRequiredFields(Map<String, Object> item, String... keys) {
  return Arrays.stream(keys).allMatch(item::containsKey);
}

Try / catch

try {
  CheckResult r = lt.check(text);
} catch (RuntimeException e) {
  if (e.getMessage().contains("doesn't contain required property")) {
    log.error("unexpected server response schema: " + e.getMessage());
  } else throw e;
}

Prevention

When it happens

Trigger: Parsing a LanguageTool server response JSON whose matches/objects lack required keys — e.g. a proxy or different server version returning a modified schema, an error JSON being parsed as a success payload, or a truncated response.

Common situations: Running a newer client against an older server (or vice versa) where response fields changed; middleboxes stripping/renaming fields; pointing the client at a non-LanguageTool endpoint that returns valid but unrelated JSON.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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