languagetool-org/languagetool · error · BadRequestException

You specified 'preferredvariants' but the parameter is now c

Error message

You specified 'preferredvariants' but the parameter is now called 'preferredVariants' (uppercase 'V') in v2 of the API

What it means

In v2 the parameter is 'preferredVariants' with an uppercase 'V'. The lowercase v1 spelling 'preferredvariants' is rejected by V2TextChecker.checkParams() so clients don't silently lose variant preferences.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/V2TextChecker.java:107

  @Override
  protected boolean getLanguageAutoDetect(Map<String, String> parameters) {
    return "auto".equals(parameters.get("language"));
  }

  @Override
  protected void checkParams(Map<String, String> parameters) {
    super.checkParams(parameters);
    if (StringTools.isEmpty(parameters.get("language"))) {
      throw new BadRequestException("Missing 'language' parameter, e.g. 'language=en-US' for American English or 'language=fr' for French");
    }
    if (parameters.get("enabled") != null) {
      throw new BadRequestException("You specified 'enabled' but the parameter is now called 'enabledRules' in v2 of the API");
    }
    if (parameters.get("disabled") != null) {
      throw new BadRequestException("You specified 'disabled' but the parameter is now called 'disabledRules' in v2 of the API");
    }
    if (parameters.get("preferredvariants") != null) {
      throw new BadRequestException("You specified 'preferredvariants' but the parameter is now called 'preferredVariants' (uppercase 'V') in v2 of the API");
    }
    if (parameters.get("autodetect") != null) {
      throw new BadRequestException("You specified 'autodetect' but automatic language detection is now activated with 'language=auto' in v2 of the API");
    }
  }
  
  @Override
  @NotNull
  protected DetectedLanguage getLanguage(String text, Map<String, String> parameters, List<String> preferredVariants,
                                         List<String> noopLangs, List<String> preferredLangs, boolean testMode) {
    String langParam = parameters.get("language");
    boolean forcePreferredLanguages = "true".equals(parameters.get("forcePreferredLanguages"));
    DetectedLanguage detectedLang = detectLanguageOfString(text, null, preferredVariants, noopLangs, preferredLangs, forcePreferredLanguages);
    Language givenLang;
    if (getLanguageAutoDetect(parameters)) {
      givenLang = detectedLang.getDetectedLanguage();
    } else {
      givenLang = parseLanguage(langParam);

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Use preferredVariants with uppercase V
  2. Fix any middleware that lowercases parameter names before forwarding
  3. Verify exact parameter spelling against the v2 documentation
  4. Add a client-side constant for the parameter name to avoid typos

Example fix

// before
params.put("preferredvariants", "en-GB");
// after
params.put("preferredVariants", "en-GB");
Defensive patterns

Strategy: validation

Validate before calling

if ('preferredvariants' in params) { params.preferredVariants = params.preferredvariants; delete params.preferredvariants; }

Try / catch

try { await check(params); } catch (e) { if (/uppercase 'V'/.test(e.message)) { /* fix casing */ } throw e; }

Prevention

When it happens

Trigger: Calling /v2/check with preferredvariants=en-GB — HTTP 400 immediately.

Common situations: Case-insensitive parameter assumptions; migrating from v1; frameworks that lowercase query keys; hand-written curl commands with wrong casing.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/907d785d6404682a. Report an issue: GitHub.