languagetool-org/languagetool · error · BadRequestException

'sourceLanguage' parameter missing - must be set when 'sourc

Error message

'sourceLanguage' parameter missing - must be set when 'sourceText' is set

What it means

The translation-style sourceText check requires knowing the source language to run the source-side analysis. When 'sourceText' is provided without 'sourceLanguage', the TextChecker constructor throws BadRequestException, since it cannot build the JLanguageTool instance for the source text.

Source

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

    }
  }

  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) {
        throw new BadRequestException("'sourceLanguage' parameter missing - must be set when 'sourceText' is set");
      }
      Language sourceLanguage = parseLanguage(parameters.get("sourceLanguage"));
      JLanguageTool sourceLt = new JLanguageTool(sourceLanguage);
      JLanguageTool targetLt = new JLanguageTool(lang);
      if (userConfig.filterDictionaryMatches()) {
        targetLt.addMatchFilter(new DictionaryMatchFilter(userConfig));
      }
      List<BitextRule> bitextRules = Tools.getBitextRules(sourceLanguage, lang);
      return Collections.singletonList(
              new CheckResults(Tools.checkBitext(parameters.get("sourceText"), aText.getPlainText(), sourceLt, targetLt, bitextRules), Collections.emptyList())
      );
    } else {
      List<CheckResults> res = new ArrayList<>();
      res.addAll(getPipelineResults(aText, lang, motherTongue, params, userConfig, listener));
      return res;
    }
  }

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Add sourceLanguage with a valid short code matching the source text, e.g. sourceLanguage=de-DE
  2. If you have no source text to compare, remove sourceText and just check the target text
  3. Validate client code so sourceText and sourceLanguage are always sent together

Example fix

// before
curl -d text=Hello -d sourceText=Hallo -d language=en-US http://server/v2/check
// after
curl -d text=Hello -d sourceText=Hallo -d sourceLanguage=de-DE -d language=en-US http://server/v2/check
Defensive patterns

Strategy: validation

Validate before calling

if (params.sourceText != null && !params.sourceLanguage) {
  throw new Error("'sourceLanguage' is required whenever 'sourceText' is set");
}

Type guard

function sourcePairIsValid(p) {
  return p.sourceText == null || (typeof p.sourceLanguage === 'string' && p.sourceLanguage.length > 0);
}

Try / catch

try {
  return await check({ ...params });
} catch (e) {
  if (e.status === 400 && /'sourceLanguage' parameter missing/.test(e.message)) {
    throw new Error('Client bug: sourceText sent without sourceLanguage');
  }
  throw e;
}

Prevention

When it happens

Trigger: POSTing to /v2/check with sourceText=... but no sourceLanguage parameter (the block at TextChecker.java:905 only creates sourceLt after parseLanguage(sourceLanguage)); also triggered indirectly when sourceLanguage itself is an invalid code (see parseLanguage).

Common situations: Clients supporting the sourceText feature sending only the source text; older API wrappers predating the sourceLanguage requirement; copy-pasted examples from plain-check requests extended with sourceText.

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