languagetool-org/languagetool · error · IllegalArgumentException
<dir.getAbsolutePath()> is not a directory, cannot use recur
Error message
<dir.getAbsolutePath()> is not a directory, cannot use recursion
What it means
Main.runRecursive recurses into a directory to process every file. File.listFiles() returns null when the path is not a directory (or is unreadable), and the method converts that into IllegalArgumentException '<path> is not a directory, cannot use recursion'. This is the recursion-mode (-r/--recursive) guard.
Source
Thrown at languagetool-commandline/src/main/java/org/languagetool/commandline/Main.java:315
ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE,
ByteOrderMark.UTF_32BE,ByteOrderMark.UTF_32LE);
if (bomIn.hasBOM() && encoding == null) {
charsetName = bomIn.getBOMCharsetName();
}
is = bomIn;
}
return new InputStreamReader(new BufferedInputStream(is), charsetName);
}
private boolean isStdIn(String filename) {
return "-".equals(filename);
}
private void runRecursive(String filename, String encoding, boolean xmlFiltering, JLanguageTool.Level level) {
File dir = new File(filename);
File[] files = dir.listFiles();
if (files == null) {
throw new IllegalArgumentException(dir.getAbsolutePath() + " is not a directory, cannot use recursion");
}
for (File file : files) {
try {
if (file.isDirectory()) {
runRecursive(file.getAbsolutePath(), encoding, xmlFiltering, level);
} else {
if (options.isLineByLine()) {
runOnFileLineByLine(file.getAbsolutePath(), encoding, level);
} else {
runOnFile(file.getAbsolutePath(), encoding, xmlFiltering);
}
}
} catch (Exception e) {
throw new RuntimeException("Could not check text in file " + file, e);
}
}
}
View on GitHub (pinned to 2e990059ce)
Solutions
- Pass a directory (not a file) when using -r/--recursive
- Verify the path exists and is readable before running (e.g. `[ -d "$DIR" ]` or File.isDirectory())
- Drop -r for single-file input
- Fix filesystem permissions if the directory cannot be read
Example fix
// before
ltMain.runRecursive("notes.txt", "utf-8", false, null);
// after
File dir = new File("notes/");
if (dir.isDirectory()) {
ltMain.runRecursive(dir.getAbsolutePath(), "utf-8", false, null);
} Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(path);
if (!dir.isDirectory()) {
throw new IllegalArgumentException(path + " must be an existing, readable directory when using --recursive");
} Type guard
static boolean isReadableDirectory(String path) {
File d = new File(path);
return d.isDirectory() && d.canRead();
} Try / catch
try {
runRecursive(path, encoding, xmlFiltering, level);
} catch (IllegalArgumentException e) {
if (e.getMessage().endsWith("is not a directory, cannot use recursion")) {
System.err.println("--recursive requires a directory; got: " + path);
System.exit(2);
}
throw e;
} Prevention
- Check File.isDirectory() (or [ -d "$DIR" ]) before enabling -r/--recursive
- Use -r only for directory inputs; omit it for single files
- Verify read permissions on the target directory
- Validate paths exist to catch typos before the run
When it happens
Trigger: Passing -r/--recursive together with a plain file (or a nonexistent path) instead of a directory, e.g. `languagetool -r -l en file.txt`; also directories the process cannot read cause listFiles() to return null and the same error.
Common situations: Enabling recursion in a script that sometimes receives single files; path typos so the directory does not exist; permission problems on the directory.
Related errors
- You cannot list unknown words in JSON output format
- JSON output format makes no sense for profiling
- Applying suggestions makes no sense for profiling
- Tagging makes no sense for profiling
- Unknown parameter: <arg>
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/ba3b0176272e8ac9.
Report an issue: GitHub.