{"record":{"id":"b911c47bf7497b73","repo":"languagetool-org/languagetool","slug":"invalid-word-you-can-only-add-words-that-don-t-co","errorCode":null,"errorMessage":"Invalid word, you can only add words that don't contain spaces: ''","messagePattern":"Invalid word, you can only add words that don't contain spaces: ''","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java","lineNumber":326,"sourceCode":"    }\n  }\n\n  @Override\n  List<DictGroupEntry> getDictGroups(Long userId) {\n    return Collections.emptyList();\n  }\n\n  @Override\n  Long getOrCreateDictGroup(Long userId, String groupName) {\n    throw new NotImplementedException(NON_PREMIUM_MSG);\n  }\n\n  private void validateWord(String word) {\n    if (word == null || word.trim().isEmpty()) {\n      throw new BadRequestException(\"Invalid word, cannot be empty or whitespace only\");\n    }\n    if (WHITESPACE_PATTERN.matcher(word).matches()) {\n      throw new BadRequestException(\"Invalid word, you can only add words that don't contain spaces: '\" + word + \"'\");\n    }\n  }\n\n  /** For unit tests only! */\n  @Override\n  public void createAndFillTestTables(boolean mysql, List<String> skipStatements) {\n    try (SqlSession session = sqlSessionFactory.openSession(true)) {\n      System.out.println(\"Setting up tables and adding test user...\");\n      String[] statements = { \"org.languagetool.server.UserDictMapper.createUserTable\",\n        \"org.languagetool.server.UserDictMapper.createIgnoreWordTable\" };\n      for (String statement : statements) {\n        if (skipStatements.contains(statement)) {\n          continue;\n        }\n        if (mysql) {\n          session.insert(statement + \"MySQL\");\n        } else {\n          session.insert(statement);","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java#L308-L344","documentation":"validateWord rejects words containing whitespace matched by WHITESPACE_PATTERN, throwing BadRequestException. User vocabulary entries must be single tokens without spaces; the exception message embeds the offending word.","triggerScenarios":"Calling addWord with a string containing a space, e.g. \"hello world\" or multi-word phrases.","commonSituations":"User pastes a phrase into an 'add to dictionary' UI field; splitting of comma-separated input done with the wrong delimiter; adding n-grams or phrases instead of single words.","solutions":["Split multi-word input on whitespace and add each token individually.","Validate client-side that the word matches ^\\S+$ before calling addWord.","Show a UI validation message preventing spaces in the input field.","If phrases are needed, use a premium dictionary group or your own storage instead of the user vocabulary API."],"exampleFix":"// before\nserver.addWord(userId, \"hello world\");\n// after\nfor (String token : phrase.trim().split(\"\\\\s+\")) {\n  server.addWord(userId, token);\n}","handlingStrategy":"validation","validationCode":"function isSingleToken(w) {\n  return /^\\S+$/.test(w);\n}\nif (!isSingleToken(word)) throw new Error('word must not contain spaces');","typeGuard":"boolean isSingleToken(String w) {\n  return w != null && w.matches(\"\\\\S+\");\n}","tryCatchPattern":"try {\n  api.addWord(userId, word);\n} catch (BadRequestException e) {\n  if (e.getMessage().contains(\"spaces\")) {\n    word.trim().split(\"\\\\s+\").forEach(w -> api.addWord(userId, w));\n  } else throw e;\n}","preventionTips":["Split phrases into tokens before adding to the dictionary","Constrain dictionary UI inputs to single tokens","Normalize input (trim + collapse whitespace) before validation"],"tags":["validation","bad-request","dictionary"],"backgroundTag":"invalid-argument-value","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"}