MuntashirAkon/AppManager · error · FileNotFoundException
+ path + does not exist.
Error message
+ path + does not exist.
What it means
VirtualFileSystem.newInputStream(path) throws FileNotFoundException when getNode(path) returns null, i.e. the path does not resolve to a node in this virtual filesystem. The library requires the target to exist (and be a readable file) before opening an input stream. Unlike java.io.FileInputStream, existence is checked against the VFS tree, not the raw OS filesystem.
Source
Thrown at app/src/main/java/io/github/muntashirakon/io/fs/VirtualFileSystem.java:968
public void setUidGid(String path, int uid, int gid) {
// TODO: 7/12/22 This should either throw ErrnoException or a boolean value
checkMounted();
}
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.");View on GitHub (pinned to 0152f468fc)
Solutions
- Verify the path exists first via VFS exists()/ls on the parent directory before calling newInputStream
- Check for races: ensure no other thread/process deletes the entry between creation and read
- Re-check the path string for typos, casing, and the VFS's expected separator
- If the source was unmounted/remounted, re-resolve the path against the new mount instead of reusing a stale absolute path
Example fix
// before
FileInputStream in = vfs.newInputStream("/docs/config.json");
// after
if (vfs.exists("/docs/config.json")) {
FileInputStream in = vfs.newInputStream("/docs/config.json");
} else {
// create, mount, or surface a user-facing "file missing" state
} Defensive patterns
Strategy: try-catch
Validate before calling
if (vfs == null || !vfs.exists(path)) throw new IllegalStateException("VFS path missing: " + path); Type guard
boolean isReadableFile(VirtualFileSystem vfs, String path) {
try {
return vfs.checkAccess(path, OsConstants.R_OK);
} catch (IOException e) {
return false;
}
} Try / catch
try {
FileInputStream in = vfs.newInputStream(path);
} catch (FileNotFoundException e) {
// path missing in VFS: recreate/mount or inform user
} catch (IOException e) {
// access or type problem
} Prevention
- Always existence-check VFS paths before stream calls
- Do not cache VFS paths across unmount/remount cycles
- Normalize path separators/casing through one helper
- Synchronize file lifecycle (create/delete/read) on a common lock
When it happens
Trigger: Calling newInputStream() with a path that was never created/mounted in the VFS, a path that was deleted (or whose node was evicted from the VFS cache), or a misspelled/incorrectly-cased path. Also when checkAccess(R_OK) passes but the node lookup fails (e.g. dangling entry after an unmount).
Common situations: Opening a file before the remote source is mounted or lazily populated; racing with a delete/removal from another thread; constructing paths with wrong separators or case; stale path cached from a previous mount session.
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
- + path + is not a file.
- 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/954cde588a3db369.
Report an issue: GitHub.