languagetool-org/languagetool · error · BadRequestException

Missing 'text' or 'data' parameter

Error message

Missing 'text' or 'data' parameter

What it means

A check request must carry the text either as the 'text' parameter (plain text) or as 'data' (annotated JSON text). checkParams throws BadRequestException when both are absent, since there is nothing to check.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/TextChecker.java:886

  }

  private List<String> getUserDictWords(UserLimits limits, List<String> groups) {
    DatabaseAccess db = DatabaseAccess.getInstance();
    return db.getWords(limits, groups, RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);
  }

  private List<Rule> getUserRules(UserLimits limits, Language lang, List<String> groups) {
    if (limits.getPremiumUid() != null && DatabaseAccess.isReady()) {
      DatabaseAccess db = DatabaseAccess.getInstance();
      return db.getRules(limits, lang, groups);
    } else {
      return Collections.emptyList();
    }
  }

  protected void checkParams(Map<String, String> parameters) {
    if (parameters.get("text") == null && parameters.get("data") == null) {
      throw new BadRequestException("Missing 'text' or 'data' parameter");
    }
  }

  private List<CheckResults> getRuleMatches(AnnotatedText aText, Language lang,
                                         Language motherTongue, Map<String, String> parameters,
                                         QueryParams params, UserConfig userConfig,
                                         /*DetectedLanguage detLang,
                                         List<String> preferredLangs, List<String> preferredVariants,*/
                                         RuleMatchListener listener) throws Exception {
    if (cache != null && cache.requestCount() > 0 && cache.requestCount() % CACHE_STATS_PRINT == 0) {
      String sentenceHitPercentage = String.format(Locale.ENGLISH, "%.2f", cache.getSentenceCache().stats().hitRate() * 100.0f);
      String matchesHitPercentage = String.format(Locale.ENGLISH, "%.2f", cache.getMatchesCache().stats().hitRate() * 100.0f);
      String remoteHitPercentage = String.format(Locale.ENGLISH, "%.2f", cache.getRemoteMatchesCache().stats().hitRate() * 100.0f);
      log.info("Cache stats: " + sentenceHitPercentage + "% / " + matchesHitPercentage + "% / " + remoteHitPercentage + "% hit rate");
    }

    if (parameters.get("sourceText") != null) {
      if (parameters.get("sourceLanguage") == null) {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Add the text parameter: text=Your+text+to+check
  2. Or supply the annotated-text JSON via the data parameter for advanced markup
  3. Verify the request uses application/x-www-form-urlencoded fields the server actually parses (check client serialization)
  4. Log the outgoing params before the call to confirm 'text'/'data' keys are present

Example fix

// before
curl -d language=en-US http://server/v2/check
// after
curl -d text=Hello+world -d language=en-US http://server/v2/check
Defensive patterns

Strategy: validation

Validate before calling

function buildCheckParams(text, options = {}) {
  if (text == null && options.data == null) {
    throw new Error("Provide either 'text' or 'data' before calling /v2/check");
  }
  return { text, ...options };
}

Type guard

function hasCheckPayload(p) {
  return p != null && (typeof p.text === 'string' ? p.text.length > 0 : p.data != null);
}

Try / catch

try {
  return await api.check(params);
} catch (e) {
  if (e.status === 400 && /Missing 'text' or 'data'/.test(e.message)) {
    throw new Error('Request payload was empty; check client serialization (form-encoding vs JSON)');
  }
  throw e;
}

Prevention

When it happens

Trigger: POSTing /v2/check without a text or data field — e.g. only language=... and options, an empty body, a misnamed field (txt=, content=), or multipart/JSON bodies whose fields are not parsed into the params map.

Common situations: Hand-rolled curl calls missing -d text=..., form encoding mistakes, clients sending JSON bodies to an endpoint that expects form-encoded parameters, or a parameter name typo after refactoring.

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