languagetool-org/languagetool · error · IllegalArgumentException

apiKey must be set

Error message

apiKey must be set

What it means

getUserId(username, apiKey) throws IllegalArgumentException when the apiKey is null, empty, or whitespace-only. Both username and apiKey must be present for API-key-based user lookup against the database-backed path.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java:209

        logger.info("Did not add '" + word + "' for user " + userId + " to list of ignored words, already exists");
        return false;
      } else {
        Date now = new Date();
        map.put("created_at", now);
        map.put("updated_at", now);
        int affectedRows = session.insert("org.languagetool.server.UserDictMapper.addWord", map);
        logger.info("Added '" + word + "' for user " + userId + " to list of ignored words, affectedRows: " + affectedRows);
        return affectedRows == 1;
      }
    }
  }

  Long getUserId(String username, String apiKey) {
    if (username == null || username.trim().isEmpty()) {
      throw new IllegalArgumentException("username must be set");
    }
    if (apiKey == null || apiKey.trim().isEmpty()) {
      throw new IllegalArgumentException("apiKey must be set");
    }
    if (sqlSessionFactory == null) {
      throw new AuthException("This is the endpoint for the basic version of LanguageTool. " +
        "When using 'username' and 'apiKey' to access the premium version, use api.languagetoolplus.com instead.");
    }
    try {
      Long value = dbLoggingCache.get(String.format("user_%s_%s", username, apiKey), () -> {
        try (SqlSession session = sqlSessionFactory.openSession()) {
          Map<Object, Object> map = new HashMap<>();
          map.put("username", username);
          map.put("apiKey", apiKey);
          Long id = session.selectOne("org.languagetool.server.UserDictMapper.getUserIdByApiKey", map);
          if (id == null) {
            return -1L;
          }
          return id;
        }
      });

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Supply a valid non-empty apiKey together with the username.
  2. Generate/copy the API key from your LanguageTool account and fix the client or environment variable holding it.
  3. Add caller-side validation that rejects empty/blank keys before the request.

Example fix

// before
String apiKey = System.getenv("LT_API_KEY"); // null/empty
api.lookup("bob", apiKey); // IllegalArgumentException: apiKey must be set
// after
String apiKey = Objects.requireNonNull(System.getenv("LT_API_KEY"), "LT_API_KEY not set");
api.lookup("bob", apiKey);
Defensive patterns

Strategy: validation

Validate before calling

if (apiKey == null || apiKey.trim().isEmpty()) {
  throw new IllegalArgumentException("apiKey must be set before calling the API");
}

Type guard

boolean hasApiKey(String k) { return k != null && !k.trim().isEmpty(); }

Try / catch

try {
  Long userId = db.getUserId(username, apiKey);
} catch (IllegalArgumentException e) {
  // prompt for/generate an API key
}

Prevention

When it happens

Trigger: Calling getUserId (or the endpoints using it, e.g. getUserInfoWithApiKey) with a username present but the apiKey missing, empty, or blank.

Common situations: User account has no API key generated yet and the empty value is sent anyway; config/env variable for the key unset so an empty string is transmitted; copying only the username into client configuration.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


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