iBotPeaches/Apktool · error · DirectoryException
file must be a directory:
Error message
file must be a directory:
What it means
FileDirectory's constructor requires an existing directory; it throws when the given File is not currently a directory (a regular file) or does not exist at all. This is a strict precondition — FileDirectory never creates the directory.
Source
Thrown at brut.j.dir/src/main/java/brut/directory/FileDirectory.java:40
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
public class FileDirectory extends Directory {
private final File mDir;
public FileDirectory(String dirName) throws DirectoryException {
this(new File(dirName));
}
public FileDirectory(File dir) throws DirectoryException {
if (!dir.isDirectory()) {
throw new DirectoryException("file must be a directory: " + dir);
}
mDir = dir;
}
@Override
protected void load() {
mFiles = new LinkedHashSet<>();
mDirs = new LinkedHashMap<>();
File[] files = mDir.listFiles();
Arrays.sort(files, Comparator.comparing(File::getName));
for (File file : files) {
if (file.isFile()) {
mFiles.add(file.getName());
} else {
try {
mDirs.put(file.getName(), new FileDirectory(file));View on GitHub (pinned to 79b63384d7)
Solutions
- Create the directory first: Files.createDirectories(path) or OS.mkdir(dir)
- Verify with isDirectory() before constructing and fail with a clear message
- Check for typos and symlinks resolving to files (ls -ld on the path)
- If another process may delete it, construct lazily right before use
Example fix
// before
Directory dir = new FileDirectory(new File("out/res")); // not created yet
// after
File f = new File("out/res");
if (!f.isDirectory()) {
Files.createDirectories(f.toPath());
}
Directory dir = new FileDirectory(f); Defensive patterns
Strategy: validation
Validate before calling
File f = new File(path);
if (!f.isDirectory()) {
Files.createDirectories(f.toPath()); // throws if path is an existing FILE
}
Directory dir = new FileDirectory(f); Type guard
boolean isUsableDirectory(File f) {
return f.exists() && f.isDirectory() && f.canRead();
} Try / catch
try {
return new FileDirectory(dir);
} catch (DirectoryException e) {
if (e.getMessage() != null && e.getMessage().startsWith("file must be a directory")) {
throw new IllegalArgumentException("Expected a directory but got: " + dir, e);
}
throw e;
} Prevention
- Always Files.createDirectories before constructing FileDirectory
- Never assume decode output folders pre-exist
- Check for symlinks pointing at regular files on the intended path
When it happens
Trigger: Constructing FileDirectory with a path that is a file, a typo, or a not-yet-created directory; also reached via Directory.createDir chains when an intermediate step returned a non-directory.
Common situations: Assuming a decoded output folder exists before first decode; passing a path where a symlink points at a file; races where another process removes the directory between check and construction.
Related errors
- file must be a file:
- Input file (" + path + ") was not found or was not readable.
- Framework path is not a directory:
- Framework path's parent is not a directory:
- Could not create framework directory:
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/691a41b24c8920bf.
Report an issue: GitHub.