languagetool-org/languagetool · error · BadRequestException
Invalid word, cannot be empty or whitespace only
Error message
Invalid word, cannot be empty or whitespace only
What it means
validateWord rejects empty or whitespace-only words before they are stored in a user dictionary, throwing BadRequestException. A user-vocabulary entry must contain at least one non-whitespace character; the server refuses the request as a client input error.
Source
Thrown at languagetool-server/src/main/java/org/languagetool/server/DatabaseAccessOpenSource.java:323
} catch (ExecutionException e) {
logger.warn("Failure in getOrCreateClientId with client '" + client + "': ", e);
return null;
}
}
@Override
List<DictGroupEntry> getDictGroups(Long userId) {
return Collections.emptyList();
}
@Override
Long getOrCreateDictGroup(Long userId, String groupName) {
throw new NotImplementedException(NON_PREMIUM_MSG);
}
private void validateWord(String word) {
if (word == null || word.trim().isEmpty()) {
throw new BadRequestException("Invalid word, cannot be empty or whitespace only");
}
if (WHITESPACE_PATTERN.matcher(word).matches()) {
throw new BadRequestException("Invalid word, you can only add words that don't contain spaces: '" + word + "'");
}
}
/** For unit tests only! */
@Override
public void createAndFillTestTables(boolean mysql, List<String> skipStatements) {
try (SqlSession session = sqlSessionFactory.openSession(true)) {
System.out.println("Setting up tables and adding test user...");
String[] statements = { "org.languagetool.server.UserDictMapper.createUserTable",
"org.languagetool.server.UserDictMapper.createIgnoreWordTable" };
for (String statement : statements) {
if (skipStatements.contains(statement)) {
continue;
}
if (mysql) {View on GitHub (pinned to 2e990059ce)
Solutions
- Trim and check the word for emptiness on the client before calling addWord.
- Filter out empty/whitespace-only tokens before batch-adding words.
- Fix the upstream extraction logic producing empty tokens.
- Ensure the API parameter is actually provided in the request (not dropped/null).
Example fix
// before
server.addWord(userId, word);
// after
String trimmed = word == null ? "" : word.trim();
if (!trimmed.isEmpty()) {
server.addWord(userId, trimmed);
} Defensive patterns
Strategy: validation
Validate before calling
function isValidWord(w) {
return typeof w === 'string' && w.trim().length > 0;
}
if (!isValidWord(word)) throw new Error('word must be non-empty'); Type guard
boolean isNonEmptyString(Object o) {
return o instanceof String && !((String) o).trim().isEmpty();
} Try / catch
try {
api.addWord(userId, word);
} catch (BadRequestException e) {
if (e.getMessage().contains("cannot be empty")) {
log.warn("Skipping empty word for user " + userId);
} else throw e;
} Prevention
- Trim input before sending to the API
- Skip empty tokens in batch add operations
- Validate form fields as required+non-blank in the UI
When it happens
Trigger: Calling addWord (or the /vocabulary REST endpoint) with a word that is null, "", or consists only of whitespace (e.g. " ", "\t").
Common situations: Client sends an empty word param from a form/UI; word extracted by a buggy regex that yields empty string; trimming done after validation; JSON body field missing and defaulted to empty.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid word, you can only add words that don't contain spac
- No rules are active. Please make sure your rule ids (<option
- Probability must be >= 0:
- <antipattern>s can only contain <example>s without errors (i
- 'skip' should be between -1 and ${Byte.MAX_VALUE}
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/63f086cb54fdf3cd.
Report an issue: GitHub.