languagetool-org/languagetool · error · BadRequestException
Could not decode query. Query length: Request method:
Error message
Could not decode query. Query length: Request method:
What it means
Thrown when URL-decoding of a query/body parameter fails because the value contains malformed percent-encoding (e.g. a lone '%' or invalid escape sequence). The server rejects the whole request as a BadRequest rather than skipping the bad parameter.
Source
Thrown at languagetool-server/src/main/java/org/languagetool/server/LanguageToolHttpHandler.java:496
if (query != null) {
parameters.putAll(getParameterMap(query, httpExchange));
}
return parameters;
}
private Map<String, String> getParameterMap(String query, HttpExchange httpExchange) throws UnsupportedEncodingException {
String[] pairs = StringUtils.split(query, '&');
Map<String, String> parameters = new HashMap<>();
for (String pair : pairs) {
int delimPos = pair.indexOf('=');
if (delimPos != -1) {
String param = pair.substring(0, delimPos);
String key = URLDecoder.decode(param, ENCODING);
try {
String value = URLDecoder.decode(pair.substring(delimPos + 1), ENCODING);
parameters.put(key, value);
} catch (IllegalArgumentException e) {
throw new BadRequestException("Could not decode query. Query length: " + query.length() +
" Request method: " + httpExchange.getRequestMethod());
}
}
}
return parameters;
}
}
View on GitHub (pinned to 2e990059ce)
Solutions
- Percent-encode all parameter values (encode '%' as %25) before sending, e.g. with encodeURIComponent or curl --data-urlencode
- Validate/fix the query string for stray '%' characters
- Use an HTTP client library's form encoding instead of manual string concatenation
Example fix
// before
fetch('/v2/check?text=' + text)
// after
fetch('/v2/check?text=' + encodeURIComponent(text)) Defensive patterns
Strategy: validation
Validate before calling
function safeParam(v) {
const s = String(v);
if (/%(?![0-9A-Fa-f]{2})/.test(s)) throw new Error('Malformed percent-encoding: ' + s);
return encodeURIComponent(s);
} Try / catch
try {
return await fetch(`/v2/check?text=${safeParam(text)}&language=en-US`);
} catch (e) {
if (e.message.includes('Could not decode query')) {
console.error('Fix percent-encoding: escape % as %25');
}
throw e;
} Prevention
- Always URL-encode parameter values with a standard encoder
- Never build query strings by string concatenation of raw user text
- Beware double-encoding when proxies also encode
When it happens
Trigger: GET query string or form body containing invalid URL-encoding such as '%' not followed by two hex digits, e.g. text=100% done without encoding the percent sign.
Common situations: Hand-built query strings where '%' characters are not escaped to %25, double-encoded values, clients sending raw bytes that aren't valid UTF-8 percent-escapes, or templates interpolating unsanitized user text into URLs.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- Missing 'text' or 'data' parameter
- Use parameter 'dicts', not 'dict' in GET /words API method.
- 'lang' parameter missing
- 'ruleId' parameter missing
- Rule '<ruleId>' not found for language <lang> (LanguageTool
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/cb8ca74b63aa2ffb.
Report an issue: GitHub.