languagetool-org/languagetool · error · BadRequestException

Missing 'text' or 'data' parameter

Error message

Missing 'text' or 'data' parameter

What it means

handleCheckRequest in ApiV2 requires the check request to carry the text to proofread. It accepts either a 'text' parameter (plain text) or a 'data' parameter containing JSON with 'text' or 'annotation'. If neither is supplied (or 'data' holds neither key), the server rejects the request with a BadRequestException so it never runs the grammar check.

Source

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

    } 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;
    }
    textChecker.checkText(aText, httpExchange, parameters, errorRequestLimiter, remoteAddress);
  }

  private void handleIpLogMatch(HttpExchange httpExchange, String remoteAddress, Map<String, String> parameters) {
    Logger logger = LoggerFactory.getLogger(ApiV2.class);
    InetSocketAddress localAddress = httpExchange.getLocalAddress();
    logger.info(String.format("Found log-my-IP text in request from: %s to: %s, requestParams: %s", remoteAddress, localAddress.toString(), parameters));
  }

  private void handleWordsRequest(HttpExchange httpExchange, Map<String, String> params, HTTPServerConfig config) throws Exception {
    ensureGetMethod(httpExchange, "/words");

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Add 'text=<your text>' to the request body (form field, not query string, for POST).
  2. If using 'data', wrap the payload as JSON with a 'text' key: data={"text":"Hello"} or an 'annotation' array.
  3. Check that your HTTP client actually sends the request body and that the Content-Type matches the encoding you use.
  4. Verify the parameter names are exactly 'text', 'data', or 'annotation' — case-sensitive.

Example fix

// before
curl -X POST https://api.languagetool.org/v2/check -d 'language=en-US'
// after
curl -X POST https://api.languagetool.org/v2/check -d 'language=en-US' --data-urlencode 'text=This is a test.'
Defensive patterns

Strategy: validation

Validate before calling

if (body.text == null && body.data == null) throw new Error('v2/check requires "text" or "data"');
if (body.data != null) {
  const d = typeof body.data === 'string' ? JSON.parse(body.data) : body.data;
  if (d.text == null && d.annotation == null) throw new Error('"data" requires "text" or "annotation"');
}

Prevention

When it happens

Trigger: POST /v2/check with no 'text' field; POST with 'data' whose JSON object contains neither 'text' nor 'annotation'; clients sending the payload under a misspelled key like 'txt' or 'content'.

Common situations: Clients switching from form-encoded 'text' to the annotated 'data' JSON format but forgetting the inner 'text' key; automated scripts that drop the body entirely; proxies or HTTP libraries silently discarding multipart/form-data bodies.

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/daa25753d2bbc3ed. Report an issue: GitHub.