{"record":{"id":"e2eb99d818fa9ed0","repo":"languagetool-org/languagetool","slug":"apikey-must-be-set","errorCode":null,"errorMessage":"apiKey must be set","messagePattern":"apiKey must be set","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java","lineNumber":209,"sourceCode":"        logger.info(\"Did not add '\" + word + \"' for user \" + userId + \" to list of ignored words, already exists\");\n        return false;\n      } else {\n        Date now = new Date();\n        map.put(\"created_at\", now);\n        map.put(\"updated_at\", now);\n        int affectedRows = session.insert(\"org.languagetool.server.UserDictMapper.addWord\", map);\n        logger.info(\"Added '\" + word + \"' for user \" + userId + \" to list of ignored words, affectedRows: \" + affectedRows);\n        return affectedRows == 1;\n      }\n    }\n  }\n\n  Long getUserId(String username, String apiKey) {\n    if (username == null || username.trim().isEmpty()) {\n      throw new IllegalArgumentException(\"username must be set\");\n    }\n    if (apiKey == null || apiKey.trim().isEmpty()) {\n      throw new IllegalArgumentException(\"apiKey must be set\");\n    }\n    if (sqlSessionFactory == null) {\n      throw new AuthException(\"This is the endpoint for the basic version of LanguageTool. \" +\n        \"When using 'username' and 'apiKey' to access the premium version, use api.languagetoolplus.com instead.\");\n    }\n    try {\n      Long value = dbLoggingCache.get(String.format(\"user_%s_%s\", username, apiKey), () -> {\n        try (SqlSession session = sqlSessionFactory.openSession()) {\n          Map<Object, Object> map = new HashMap<>();\n          map.put(\"username\", username);\n          map.put(\"apiKey\", apiKey);\n          Long id = session.selectOne(\"org.languagetool.server.UserDictMapper.getUserIdByApiKey\", map);\n          if (id == null) {\n            return -1L;\n          }\n          return id;\n        }\n      });","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java#L191-L227","documentation":"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.","triggerScenarios":"Calling getUserId (or the endpoints using it, e.g. getUserInfoWithApiKey) with a username present but the apiKey missing, empty, or blank.","commonSituations":"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.","solutions":["Supply a valid non-empty apiKey together with the username.","Generate/copy the API key from your LanguageTool account and fix the client or environment variable holding it.","Add caller-side validation that rejects empty/blank keys before the request."],"exampleFix":"// before\nString apiKey = System.getenv(\"LT_API_KEY\"); // null/empty\napi.lookup(\"bob\", apiKey); // IllegalArgumentException: apiKey must be set\n// after\nString apiKey = Objects.requireNonNull(System.getenv(\"LT_API_KEY\"), \"LT_API_KEY not set\");\napi.lookup(\"bob\", apiKey);","handlingStrategy":"validation","validationCode":"if (apiKey == null || apiKey.trim().isEmpty()) {\n  throw new IllegalArgumentException(\"apiKey must be set before calling the API\");\n}","typeGuard":"boolean hasApiKey(String k) { return k != null && !k.trim().isEmpty(); }","tryCatchPattern":"try {\n  Long userId = db.getUserId(username, apiKey);\n} catch (IllegalArgumentException e) {\n  // prompt for/generate an API key\n}","preventionTips":["Fail fast on empty env/config values holding the API key.","Generate the API key before enabling authenticated requests.","Use Objects.requireNonNull or startup validation for credential config."],"tags":["java","validation","authentication","missing-api-key"],"backgroundTag":"missing-api-key","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"}