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
- Add 'text=<your text>' to the request body (form field, not query string, for POST).
- If using 'data', wrap the payload as JSON with a 'text' key: data={"text":"Hello"} or an 'annotation' array.
- Check that your HTTP client actually sends the request body and that the Content-Type matches the encoding you use.
- 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
- Always include either a 'text' form field or a JSON 'data' payload in /v2/check requests.
- Verify the HTTP client sends the body for POST and uses the right Content-Type.
- Keep parameter names exact: 'text', 'data', 'annotation'.
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
- 'lang' parameter missing
- 'ruleId' parameter missing
- Use parameter 'dicts', not 'dict' in GET /words API method.
- Rule '<ruleId>' not found for language <lang> (LanguageTool
- Expected Basic Authentication
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/daa25753d2bbc3ed.
Report an issue: GitHub.