languagetool-org/languagetool · error · IllegalArgumentException

Use parameter 'dicts', not 'dict' in GET /words API method.

Error message

Use parameter 'dicts', not 'dict' in GET /words API method.

What it means

The GET /v2/words endpoint was changed to accept only the plural parameter 'dicts' (a comma-separated list of dictionary names); the old singular 'dict' parameter is explicitly rejected with an IllegalArgumentException to force callers to migrate. The exception is thrown before any dictionary lookup happens.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/ApiV2.java:196

  }

  private void handleIpLogMatch(HttpExchange httpExchange, String remoteAddress, Map<String, String> parameters) {
    Logger logger = LoggerFactory.getLogger(ApiV2.class);
    InetSocketAddress localAddress = httpExchange.getLocalAddress();
    logger.info(String.format("Found log-my-IP text in request from: %s to: %s, requestParams: %s", remoteAddress, localAddress.toString(), parameters));
  }

  private void handleWordsRequest(HttpExchange httpExchange, Map<String, String> params, HTTPServerConfig config) throws Exception {
    ensureGetMethod(httpExchange, "/words");
    UserLimits limits = getUserLimits(params, config);
    DatabaseAccess db = DatabaseAccess.getInstance();
    int offset = params.get("offset") != null ? Integer.parseInt(params.get("offset")) : 0;
    int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit")) : 10;
    logger.info("Started reading dictionary for user: {}, offset: {}, limit: {}, dict_cache: {}, dict: {}",
      limits.getPremiumUid(), offset, limit, limits.getDictCacheSize(), params.get("dict"));

    if (params.containsKey("dict")) {
      throw new IllegalArgumentException("Use parameter 'dicts', not 'dict' in GET /words API method.");
    }

    // optional parameter: groups in comma separated list
    List<String> groups = null;
    if (params.containsKey("dicts")) {
      groups = Arrays.asList(params.get("dicts").split(","));
    } else if (limits.getAccount() != null &&
               limits.getAccount().getDefaultDictionary() != null &&
               !limits.getAccount().getDefaultDictionary().isEmpty()) {
      groups = Collections.singletonList(limits.getAccount().getDefaultDictionary());
    }
    long start = System.nanoTime();
    List<String> words = db.getWords(limits, groups, offset, limit);
    //List<String> words = db.getWords(limits.getPremiumUid(), groups, offset, limit);
    long durationMilliseconds = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
    logger.info("Finished reading dictionary for user: {}, offset: {}, limit: {}, dict_cache: {}, dict: {}, size: {} in {}ms",
      limits.getPremiumUid(), offset, limit, limits.getDictCacheSize(), params.get("dict"), words.size(), durationMilliseconds);
    writeListResponse("words", words, httpExchange);

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Rename the query parameter from 'dict' to 'dicts' in the request URL.
  2. If you need multiple dictionaries, pass them as a comma-separated list: dicts=name1,name2.
  3. Update any client SDK or wrapper that still emits the deprecated 'dict' parameter.

Example fix

// before
GET /v2/words?dict=my_personal_dict&username=u&token=t
// after
GET /v2/words?dicts=my_personal_dict&username=u&token=t
Defensive patterns

Strategy: validation

Validate before calling

const url = new URL('/v2/words', base);
if (url.searchParams.has('dict')) throw new Error('Use "dicts", not "dict", for GET /v2/words');

Prevention

When it happens

Trigger: Calling GET /v2/words with '?dict=my_dict' instead of '?dicts=my_dict'; legacy client code written against the pre-rename API still passing 'dict'.

Common situations: Old integrations or bookmarks written before the API rename; copied example snippets from outdated blog posts or documentation; wrappers that still serialize a 'dict' query parameter.

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