languagetool-org/languagetool · error · BadRequestException

Could not parse JSON from 'data' parameter

Error message

Could not parse JSON from 'data' parameter

What it means

When the 'data' parameter is supplied to /v2/check, the server parses it as JSON with Jackson. If the value is not valid JSON (JsonProcessingException), it throws BadRequestException with this message and the parse error as cause.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/ApiV2.java:157

    ServerTools.setCommonHeaders(httpExchange, JSON_CONTENT_TYPE, allowOriginUrl);
    httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.getBytes(ENCODING).length);
    httpExchange.getResponseBody().write(response.getBytes(ENCODING));
    ServerMetricsCollector.getInstance().logResponse(HttpURLConnection.HTTP_OK);
  }

  private void handleCheckRequest(HttpExchange httpExchange, Map<String, String> parameters, ErrorRequestLimiter errorRequestLimiter, String remoteAddress, HTTPServerConfig config) throws Exception {
    AnnotatedText aText;
    if (parameters.containsKey("text") && parameters.containsKey("data")) {
      throw new BadRequestException("Set only 'text' or 'data' parameter, not both");
    } else if (parameters.containsKey("text")) {
      aText = new AnnotatedTextBuilder().addText(parameters.get("text")).build();
    } else if (parameters.containsKey("data")) {
      ObjectMapper mapper = new ObjectMapper();
      JsonNode data;
      try {
        data = mapper.readTree(parameters.get("data"));
      } catch (JsonProcessingException e) {
        throw new BadRequestException("Could not parse JSON from 'data' parameter", e);
      }
      if (data.get("text") != null && data.get("annotation") != null) {
        throw new BadRequestException("'data' key in JSON requires either 'text' or 'annotation' key, not both");
      } else if (data.get("text") != null) {
        aText = getAnnotatedTextFromString(data, data.get("text").asText());
      } else if (data.get("annotation") != null) {
        aText = getAnnotatedTextFromJson(data);
      } else {
        throw new BadRequestException("'data' key in JSON requires 'text' or 'annotation' key");
      }
    } else {
      throw new BadRequestException("Missing 'text' or 'data' parameter");
    }
    //get from config
    if (config.logIp && aText.getPlainText().trim().equals(config.logIpMatchingPattern)) {
      handleIpLogMatch(httpExchange, remoteAddress, parameters);
      //no need to check text again rules
      return;

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Validate the JSON with a parser before sending it
  2. Serialize the data object with a JSON library instead of string concatenation
  3. Send it correctly URL-encoded (e.g. curl --data-urlencode)
  4. Check the cause JsonProcessingException for the exact position of the syntax error

Example fix

// before
curl -d 'data={text: "Hello"}' --data-urlencode 'language=en-US' http://server:8081/v2/check
// after
curl --data-urlencode 'data={"text":"Hello"}' --data-urlencode 'language=en-US' http://server:8081/v2/check
Defensive patterns

Strategy: validation

Validate before calling

let parsed;
try { parsed = JSON.parse(dataPayload); }
catch (e) { throw new Error('data must be valid JSON: ' + e.message); }

Type guard

function isValidJson(s) { try { JSON.parse(s); return true; } catch { return false; } }

Try / catch

try {
    const res = await check({ data: jsonPayload });
} catch (e) {
    if (/Could not parse JSON/.test(e.message)) {
        console.error('Fix JSON syntax in data parameter');
    } else throw e;
}

Prevention

When it happens

Trigger: POST /v2/check with data=... containing malformed JSON: unquoted strings, trailing commas, single quotes, HTML-encoding artifacts, or truncated payloads.

Common situations: Manually built JSON without escaping quotes/newlines; clients sending URL-encoded JSON that got double-encoded; frameworks munging the raw body.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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