languagetool-org/languagetool · error · IOException

File not found: ${inputFile}

Error message

File not found: ${inputFile}

What it means

The SentenceAnnotator constructor converts the given inputFilePath into a File and throws an IOException when the path does not exist or is a directory. It needs a readable, existing data file to annotate; directories and missing paths cannot be processed.

Source

Thrown at languagetool-http-client/src/main/java/org/languagetool/remote/SentenceAnnotator.java:669

    void prepareConfiguration() throws IOException {
      CheckConfigurationBuilder cfgBuilder = new CheckConfigurationBuilder(languageCode);
      // cfgBuilder.textSessionID("-2");
      if (enabledOnlyRules.isEmpty()) {
        cfgBuilder.disabledRuleIds("WHITESPACE_RULE");
        if (!disabledRules.isEmpty()) {
          cfgBuilder.disabledRuleIds(disabledRules);
        }
      } else {
        cfgBuilder.enabledRuleIds(enabledOnlyRules).enabledOnly();
      }
      if (!userName.isEmpty() && !apiKey.isEmpty()) {
        cfgBuilder.username(userName).apiKey(apiKey).build();
      }
      ltConfig = cfgBuilder.build();
      inputFile = new File(inputFilePath);
      if (!inputFile.exists() || inputFile.isDirectory()) {
        throw new IOException("File not found: " + inputFile);
      }
      String fileName = inputFile.getName();
      // System.out.println("Analyzing file: " + fileName);
      fileName = fileName.substring(0, fileName.lastIndexOf('.'));
      if (outputFilePath.isEmpty()) {
        outputFile = new File(inputFile.getParentFile() + "/" + fileName + "-annotations.csv");
      } else {
        outputFile = new File(outputFilePath);
      }
      outStrB = new StringBuilder();
      out = new FileWriter(outputFile, true);
      cachedMatches = new HashMap<>();
      lt = new RemoteLanguageTool(Tools.getUrl(remoteServer));
    }

  }

  private static String printTimeFromStart(long start, String tag) {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Verify the path with ls (or Files.exists) and pass the exact existing file path
  2. Pass an absolute path or run from the directory containing the input file
  3. Ensure the target is a regular file, not a directory
  4. Check the file exists before constructing: new File(path).isFile()

Example fix

// before
SentenceAnnotator ann = new SentenceAnnotator("./input/annot.txt", out, ...); // file missing
// after
File f = new File("./input/annot.txt");
if (!f.isFile()) throw new IllegalArgumentException("input file missing: " + f);
SentenceAnnotator ann = new SentenceAnnotator(f.getPath(), out, ...);
Defensive patterns

Strategy: validation

Validate before calling

Path p = Paths.get(inputFilePath);
if (!Files.isRegularFile(p)) {
  throw new IllegalArgumentException("input must be an existing file: " + p.toAbsolutePath());
}

Type guard

static boolean isReadableFile(String path) {
  File f = new File(path);
  return f.isFile() && f.exists() && f.canRead();
}

Try / catch

try {
  SentenceAnnotator a = new SentenceAnnotator(inputFilePath, out, username, apiKey, ltUrl, ...);
} catch (IOException e) {
  if (e.getMessage().startsWith("File not found")) {
    System.err.println("check path (must be a file, absolute if unsure): " + e.getMessage());
  } else throw e;
}

Prevention

When it happens

Trigger: Constructing SentenceAnnotator with a path that was never created, a typo'd filename, a directory path instead of a file, or a file deleted between argument parsing and construction.

Common situations: Relative path resolved from a different working directory; path containing spaces unquoted in the shell; expecting the tool to accept a directory of files.

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/4ec533531fbdfdee. Report an issue: GitHub.