MuntashirAkon/AppManager · error · IOException
+ path + is not a file.
Error message
+ path + is not a file.
What it means
VirtualFileSystem.newInputStream(path) throws IOException("path is not a file.") when the resolved node exists but Node.isFile() is false — typically the path points to a directory. Input streams can only be opened on regular file nodes in this VFS.
Source
Thrown at app/src/main/java/io/github/muntashirakon/io/fs/VirtualFileSystem.java:971
}
public boolean createLink(String link, String target, boolean soft) {
checkMounted();
return false;
}
/* I/O APIs */
@NonNull
public FileInputStream newInputStream(String path) throws IOException {
if (!checkAccess(path, OsConstants.R_OK)) {
throw new IOException(path + " is inaccessible.");
}
Node<?> targetNode = getNode(path);
if (targetNode == null) {
throw new FileNotFoundException(path + " does not exist.");
}
if (!targetNode.isFile()) {
throw new IOException(path + " is not a file.");
}
return new FileInputStream(getCachedFile(targetNode, false));
}
@NonNull
public FileOutputStream newOutputStream(String path, boolean append) throws IOException {
if (!checkAccess(path, OsConstants.W_OK)) {
throw new IOException(path + " is inaccessible.");
}
Node<?> targetNode = getNode(path);
if (targetNode == null) {
throw new FileNotFoundException(path + " does not exist.");
}
if (!targetNode.isFile()) {
throw new IOException(path + " is not a file.");
}
return new FileOutputStream(getCachedFile(targetNode, true), append);
}View on GitHub (pinned to 0152f468fc)
Solutions
- Check node type before reading: only call newInputStream on paths known to be files (e.g. via VFS metadata/ls)
- If a directory was intended, list its children and pick the concrete file to open
- Fix path construction so it ends in a file name, not a directory
Example fix
// before
FileInputStream in = vfs.newInputStream(selectedPath); // selectedPath may be a dir
// after
if (vfs.isDirectory(selectedPath)) {
throw new IllegalArgumentException("Select a file, not a directory: " + selectedPath);
}
FileInputStream in = vfs.newInputStream(selectedPath); Defensive patterns
Strategy: validation
Validate before calling
if (vfs.isDirectory(path)) throw new IllegalArgumentException("Expected a file: " + path); Try / catch
try {
FileInputStream in = vfs.newInputStream(path);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().endsWith("is not a file.")) {
// treat as directory: list children instead
}
} Prevention
- Restrict file pickers to selectable files, or branch on directory selection
- Verify node type before opening streams
- Avoid building paths by blind concatenation of prefixes
When it happens
Trigger: Calling newInputStream() on a directory path; passing a path that resolves to a directory-like or special node (e.g. a virtual root or folder entry) instead of a leaf file.
Common situations: User selects a folder in a file picker and the app tries to read it; a config path mistakenly points at a directory expecting auto-resolution to a default file inside; path built by concatenating a prefix that already includes a directory name.
Related errors
- + path + does not exist.
- Bad mode: + mode
- + path + cannot be opened for both reading and writing.
- + path + cannot be opened for both reading.
- + path + cannot be opened for both writing.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/440b87aa2b7ef8de.
Report an issue: GitHub.