languagetool-org/languagetool · error · RuntimeException
Could not load simple replacement data from: " + path + ". E
Error message
Could not load simple replacement data from: " + path + ". Error in line '" + line + "', replacement cannot be empty
What it means
SimpleReplaceDataLoader.loadWords parses a rule-replacement file where each line must be 'wrongForm=replacement'. This RuntimeException is thrown when the right-hand side of the '=' is empty after trimming, i.e. the data file contains a line like 'word=' with no replacement.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/SimpleReplaceDataLoader.java:53
/**
* Load replacement rules from a utf-8 file in the classpath.
*/
public Map<String, List<String>> loadWords(String path) {
InputStream stream = JLanguageTool.getDataBroker().getFromRulesDirAsStream(path);
Map<String, List<String>> map = new HashMap<>();
try (Scanner scanner = new Scanner(stream, "utf-8")) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.isEmpty() || line.charAt(0) == '#') { // # = comment
continue;
}
String[] parts = line.split("=");
if (parts.length != 2) {
throw new RuntimeException("Could not load simple replacement data from: " + path + ". " +
"Error in line '" + line + "', expected format 'word=replacement'");
}
if (parts[1].trim().isEmpty()) {
throw new RuntimeException("Could not load simple replacement data from: " + path + ". " +
"Error in line '" + line + "', replacement cannot be empty");
}
String[] wrongForms = parts[0].split("\\|");
List<String> replacements = Arrays.asList(parts[1].split("\\|"));
for (String wrongForm : wrongForms) {
map.put(wrongForm, replacements);
}
}
}
return Collections.unmodifiableMap(map);
}
}
View on GitHub (pinned to 2e990059ce)
Solutions
- Open the file at 'path' named in the exception and find the offending line printed in the message.
- Add a non-empty replacement after the '=' (or remove the line if the entry is not wanted).
- Split multiple replacements with '|' if needed, e.g. 'word=fix1|fix2'.
Example fix
// before (data file) mispeled= // after (data file) mispeled=misspelled
Defensive patterns
Strategy: validation
Validate before calling
// validate replacement data lines before loading
for (String line : Files.readAllLines(Paths.get(path))) {
if (line.isEmpty() || line.startsWith("#")) continue;
String[] parts = line.split("=", -1);
if (parts.length != 2 || parts[1].trim().isEmpty())
throw new IllegalStateException("Bad line in " + path + ": " + line);
} Try / catch
try { loader.loadWords(path, language); } catch (RuntimeException e) { log.error("Invalid replacement data: " + e.getMessage()); throw e; } Prevention
- Run a linter/CI check on rule data files for empty replacements
- Never commit replacement files with lines ending in '='
- Test-load all language data files in unit tests
When it happens
Trigger: Calling loadFromPath/loadWords on a replacement data file that contains a line with an empty replacement, e.g. 'mispeled=' (nothing after '=').
Common situations: Hand-edited or incomplete language rule data files in the language resource directories; a contributor deleted the replacement but left the word; file truncated during commit.
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
- Format error in file " + path + ", line: " + line
- Format error in file " + path + ", line: " + line + ", " + "
- Incorrect number of fields: " + line
- Form has more than 1 modern form:" + line
- Replacement has more than 1 modern form:" + line
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/c32d82bb68de5113.
Report an issue: GitHub.