languagetool-org/languagetool · error · IllegalArgumentException

dictionary file does not exist or is not a file: ''

Error message

dictionary file does not exist or is not a file: ''

What it means

The `lang-xx-dictPath` config property points to a path that either does not exist on disk or is a directory rather than a regular file. LanguageTool validates this eagerly while loading dynamic spell-checker languages so misconfiguration fails at startup, not per request.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java:543

  private void addDynamicLanguages(Properties props) throws IOException {
    for (Object keyObj : props.keySet()) {
      String key = (String)keyObj;
      if (key.startsWith("lang-") && !key.contains("-dictPath")) {
        String code = key.substring("lang-".length());
        if (!code.contains("-") && code.length() != 2 && code.length() != 3) {
          throw new IllegalArgumentException("code is supposed to be a 2 (or rarely 3) character code (unless it uses a format with variant, like xx-YY): '" + code + "'");
        }
        String nameKey = "lang-" + code;
        String name = props.getProperty(nameKey);
        String dictPathKey = "lang-" + code + "-dictPath";
        String dictPath = props.getProperty(dictPathKey);
        if (dictPath == null) {
          throw new IllegalArgumentException(dictPathKey + " must be set");
        }
        File dictPathFile = new File(dictPath);
        if (!dictPathFile.exists() || !dictPathFile.isFile()) {
          throw new IllegalArgumentException("dictionary file does not exist or is not a file: '" + dictPath + "'");
        }
        ServerTools.print("Adding dynamic spell checker language " + name + ", code: " + code + ", dictionary: " + dictPath);
        Language lang = Languages.addLanguage(name, code, new File(dictPath));
        // better fail early in case of misconfiguration, so use the language now:
        if (!new File(lang.getCommonWordsPath()).exists()) {
          throw new IllegalArgumentException("Common words path not found: '" + lang.getCommonWordsPath() + "'");
        }
        JLanguageTool lt = new JLanguageTool(lang);
        lt.check("test");
      }
    }
  }

  public void setLanguageModelDirectory(String langModelDir) {
    SuggestionsOrdererConfig.setNgramsPath(langModelDir);
    languageModelDir = new File(langModelDir);
    if (!languageModelDir.exists() || !languageModelDir.isDirectory()) {
      throw new RuntimeException("LanguageModel directory not found or is not a directory: " + languageModelDir);

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Verify the path with `ls -l` and correct it in the config file
  2. Use an absolute path instead of a relative one to avoid working-directory surprises
  3. Point the property at the dictionary FILE itself, not its parent directory

Example fix

// before (properties)
lang-de-dictPath=/opt/lt/dicts/
// after (properties)
lang-de-dictPath=/opt/lt/dicts/de.dict
Defensive patterns

Strategy: validation

Validate before calling

String dictPath = props.getProperty("lang-de-dictPath");
File f = new File(dictPath);
if (!f.exists() || !f.isFile())
  throw new IllegalStateException("Dictionary missing or not a file: " + dictPath);

Try / catch

try {
  startServer(config);
} catch (IllegalArgumentException e) {
  LOG.error("Dict file problem: {}", e.getMessage());
}

Prevention

When it happens

Trigger: `dictPathFile.exists()` returns false or `isFile()` returns false for the value of `lang-xx-dictPath` in the server config properties.

Common situations: Typo in the path, dictionary file moved or deleted after config was written, relative path resolved against an unexpected working directory, or the path points to a directory containing the dictionary rather than the dictionary itself.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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