{"record":{"id":"d627dc78a1574bde","repo":"languagetool-org/languagetool","slug":"this-server-does-not-support-username-password","errorCode":null,"errorMessage":"This server does not support username/password","messagePattern":"This server does not support username/password","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java","lineNumber":129,"sourceCode":"  @Override\n  boolean deleteWordBatch(List<String> words, Long userId, String groupName) {\n    boolean deleted = false;\n    for (String word : words) {\n      if (deleteWord(word, userId)) {\n        deleted = true;\n      }\n    }\n    return deleted;\n  }\n\n  @Override\n  void addWordBatch(List<String> words, Long userId, String groupName) {\n    words.forEach(w -> addWord(w, userId));\n  }\n\n  @Override\n  UserInfoEntry getUserInfoWithPassword(String username, String password) {\n    throw new NotImplementedException(NON_PREMIUM_MSG);\n  }\n\n  @Override\n  ExtendedUserInfo getExtendedUserInfo(String user) {\n    throw new NotImplementedException(NON_PREMIUM_MSG);\n  }\n\n  @Override\n  ExtendedUserInfo getExtendedUserInfo(long userId) {\n    throw new NotImplementedException(NON_PREMIUM_MSG);\n  }\n\n  @Override\n  UserInfoEntry getUserInfoWithApiKey(String username, String apiKey) {\n    Long userId = getUserId(username, apiKey);\n    UserInfoEntry user = new UserInfoEntry(userId, username, null, null, null, null, null, null, null, null, apiKey, null, null, null);\n    return user;\n  }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java#L111-L147","documentation":"DatabaseAccessOpenSource is the open-source (non-premium) implementation of the DatabaseAccess interface. getUserInfoWithPassword() unconditionally throws NotImplementedException with NON_PREMIUM_MSG because username/password-based user lookup is a premium-only feature backed by the paid infrastructure. The open-source build simply cannot serve this operation.","triggerScenarios":"Calling the server API endpoint that authenticates a user with username + password (getUserInfoWithPassword) against a standard languagetool-server (open-source) deployment instead of api.languagetoolplus.com.","commonSituations":"Pointing a client that was built for the premium API at a self-hosted basic server; deploying the open-source server and assuming password auth is supported; older integrations using password credentials after switching to the free server.","solutions":["Use username + apiKey (token) authentication instead of username/password, which the open-source server supports when configured with a database.","Point your client at the premium endpoint api.languagetoolplus.com if you need password-based authentication.","If self-hosting, accept that password login is unavailable and use API-key auth or no auth."],"exampleFix":"// before\nPOST /v2/user  { \"username\": \"bob\", \"password\": \"secret\" } // NotImplementedException on basic server\n// after\nPOST /v2/user  { \"username\": \"bob\", \"apiKey\": \"lt-api-key\" } // or use api.languagetoolplus.com","handlingStrategy":"validation","validationCode":"if (serverIsOpenSource && credentials.containsPassword()) {\n  throw new UnsupportedOperationException(\"Password auth requires api.languagetoolplus.com\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  userInfo = api.getUserInfoWithPassword(user, pass);\n} catch (NotImplementedException e) {\n  // switch to apiKey auth or premium endpoint\n}","preventionTips":["Never send passwords to a self-hosted open-source server.","Prefer username+apiKey auth for all integrations.","Document premium-only endpoints in client code and gate them by base URL."],"tags":["java","unsupported-operation","premium-only","authentication"],"backgroundTag":"unsupported-operation","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"}