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 + "', expected format 'word=replacement'

What it means

SimpleReplaceDataLoader.loadWords reads a simple-replacement file where every non-comment line must be exactly 'word=replacement' (split('=') must yield exactly 2 parts). A line with no '=' or multiple '=' signs triggers this RuntimeException naming the file and offending line.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/SimpleReplaceDataLoader.java:49

 * @since 3.0
 */
public final class SimpleReplaceDataLoader {

  /**
   * 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

  1. Fix the line reported in the message: it must contain exactly one '=' separating word and replacement (escape or rewrite values containing '=').
  2. Comment out or remove non-data lines; only lines starting with '#' are comments.
  3. If the replacement value legitimately contains '=', restructure the data or preprocess the loader input.
  4. Validate the file (each non-comment line matches ^[^#=]+=.*$) before loading.

Example fix

// before (data file line)
question mark = ?
// after
question mark=?
Defensive patterns

Strategy: validation

Validate before calling

int i = 0;
for (String line : Files.readAllLines(Paths.get(path))) {
  i++;
  if (line.isEmpty() || line.startsWith("#")) continue;
  String[] parts = line.split("=");
  if (parts.length != 2 || parts[1].trim().isEmpty()) {
    throw new IllegalStateException("Bad replacement line " + i + " in " + path + ": '" + line + "'");
  }
}

Try / catch

try {
  data = SimpleReplaceDataLoader.loadFromPath(path);
} catch (RuntimeException e) {
  LOG.error("Replacement file invalid: {}", e.getMessage());
  throw e;
}

Prevention

When it happens

Trigger: Calling loadWords/loadFromPath on a replacement data file containing a non-empty, non-comment line without exactly one '=' separator (e.g. 'word replacement' or 'a=b=c').

Common situations: Hand-editing replacement files and using spaces instead of '=', a second '=' in a value (URLs, attribute=value pairs), saved files with comment markers other than '#', or wrong file loaded.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/48268bc5f294d71e. Report an issue: GitHub.