{"record":{"id":"f96e92120390c18a","repo":"languagetool-org/languagetool","slug":"you-can-specify-nooplanguages-only-when-also-usi","errorCode":null,"errorMessage":"You can specify 'noopLanguages' only when also using 'language=auto'","messagePattern":"You can specify 'noopLanguages' only when also using 'language=auto'","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/TextChecker.java","lineNumber":474,"sourceCode":"    List<String> dictWords = limits.getPremiumUid() != null ?\n      TelemetryProvider.INSTANCE.createSpan(SPAN_NAME_PREFIX +\"GetUserDictWords\", Attributes.empty(), () -> getUserDictWords(limits, finalDictGroups)) : Collections.emptyList();\n\n    boolean filterDictionaryMatches = \"true\".equals(params.getOrDefault(\"filterDictionaryMatches\", \"true\"));\n\n    Long textSessionId = computeTextSessionID(params.get(\"textSessionId\"), remoteAddress);\n\n    List<String> abTest = AB_TEST_SERVICE.getActiveAbTestForClient(params, config);\n\n    boolean enableHiddenRules = \"true\".equals(params.get(\"enableHiddenRules\"));\n    if (limits.hasPremium()) {\n      enableHiddenRules = false;\n    }\n\n    boolean autoDetectLanguage = getLanguageAutoDetect(params);\n    List<String> preferredVariants = getPreferredVariants(params);\n    if (params.get(\"noopLanguages\") != null && !autoDetectLanguage) {\n      ServerMetricsCollector.getInstance().logRequestError(ServerMetricsCollector.RequestErrorType.INVALID_REQUEST);\n      throw new BadRequestException(\"You can specify 'noopLanguages' only when also using 'language=auto'\");\n    }\n    List<String> noopLangs = params.get(\"noopLanguages\") != null ?\n            Arrays.asList(params.get(\"noopLanguages\").split(\",\")) : Collections.emptyList();\n    List<String> preferredLangs = params.get(\"preferredLanguages\") != null ?\n            Arrays.asList(params.get(\"preferredLanguages\").split(\",\")) : Collections.emptyList();\n    DetectedLanguage detLang = TelemetryProvider.INSTANCE.createSpan(SPAN_NAME_PREFIX + \"DetetectLanguage\", Attributes.empty(), () -> getLanguage(aText.getPlainText(), params, preferredVariants, noopLangs, preferredLangs,\n      params.getOrDefault(\"ld\", \"control\").equalsIgnoreCase(\"test\")));\n    Language lang = detLang.getGivenLanguage();\n\n    List<Rule> userRules = TelemetryProvider.INSTANCE.createSpan(SPAN_NAME_PREFIX + \"GetUserRules\", Attributes.empty(), () -> getUserRules(limits, lang, finalDictGroups));\n    String ltAgent = params.getOrDefault(\"useragent\", \"unknown\");\n    Pattern trustedSourcesPattern = config.getTrustedSources();\n    boolean trustedSource = trustedSourcesPattern == null || (limits.hasPremium() || trustedSourcesPattern.matcher(ltAgent).matches());\n    boolean optInThirdPartyAI = isOptInThirdPartyAI(limits, params, config);\n\n    // set default value for tokenType\n    UserConfig.TokenType tokenType = authHeader == null ? UserConfig.TokenType.NO_TOKEN : UserConfig.TokenType.INVALID_TOKEN;\n    JwtContent jwtContent = limits.getJwtContent();","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/TextChecker.java#L456-L492","documentation":"The optional 'noopLanguages' parameter (languages to ignore during automatic language detection) is only meaningful together with language=auto. checkText throws BadRequestException when noopLanguages is supplied but the request does not use automatic detection, logging INVALID_REQUEST metrics.","triggerScenarios":"Sending /v2/check with parameter noopLanguages set (e.g. noopLanguages=de,en) while language is a fixed code (language=en-US) or absent — getLanguageAutoDetect(params) returns false.","commonSituations":"Clients that always append detection-tuning parameters regardless of the language mode; SDK wrappers that serialize all options unconditionally; copy-pasted request examples mixing auto-detect and fixed-language settings.","solutions":["Set language=auto in the same request when using noopLanguages","Remove the noopLanguages parameter when you specify a concrete language","In client code, only include noopLanguages when the auto-detect mode is active"],"exampleFix":"// before\ncurl -d text=... -d language=en-US -d noopLanguages=de http://server/v2/check\n// after\ncurl -d text=... -d language=auto -d noopLanguages=de http://server/v2/check","handlingStrategy":"validation","validationCode":"if (params.noopLanguages && params.language !== 'auto') {\n  params.language = 'auto'; // or delete params.noopLanguages\n}","typeGuard":"function canUseNoopLanguages(p) {\n  return p.noopLanguages == null || p.language === 'auto';\n}","tryCatchPattern":null,"preventionTips":["Gate detection-tuning parameters (noopLanguages/preferredLanguages) behind the language=auto mode in client code","Never blindly serialize all options into the request","Add a unit test asserting noopLanguages is only sent with language=auto"],"tags":["http-400","query-parameters","languagetool-server"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}