{"record":{"id":"440b87aa2b7ef8de","repo":"MuntashirAkon/AppManager","slug":"path-is-not-a-file","errorCode":null,"errorMessage":"+ path + is not a file.","messagePattern":"\\+ path \\+ is not a file\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/io/fs/VirtualFileSystem.java","lineNumber":971,"sourceCode":"    }\n\n    public boolean createLink(String link, String target, boolean soft) {\n        checkMounted();\n        return false;\n    }\n\n    /* I/O APIs */\n    @NonNull\n    public FileInputStream newInputStream(String path) throws IOException {\n        if (!checkAccess(path, OsConstants.R_OK)) {\n            throw new IOException(path + \" is inaccessible.\");\n        }\n        Node<?> targetNode = getNode(path);\n        if (targetNode == null) {\n            throw new FileNotFoundException(path + \" does not exist.\");\n        }\n        if (!targetNode.isFile()) {\n            throw new IOException(path + \" is not a file.\");\n        }\n        return new FileInputStream(getCachedFile(targetNode, false));\n    }\n\n    @NonNull\n    public FileOutputStream newOutputStream(String path, boolean append) throws IOException {\n        if (!checkAccess(path, OsConstants.W_OK)) {\n            throw new IOException(path + \" is inaccessible.\");\n        }\n        Node<?> targetNode = getNode(path);\n        if (targetNode == null) {\n            throw new FileNotFoundException(path + \" does not exist.\");\n        }\n        if (!targetNode.isFile()) {\n            throw new IOException(path + \" is not a file.\");\n        }\n        return new FileOutputStream(getCachedFile(targetNode, true), append);\n    }","sourceCodeStart":953,"sourceCodeEnd":989,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/io/fs/VirtualFileSystem.java#L953-L989","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nFileInputStream in = vfs.newInputStream(selectedPath); // selectedPath may be a dir\n// after\nif (vfs.isDirectory(selectedPath)) {\n    throw new IllegalArgumentException(\"Select a file, not a directory: \" + selectedPath);\n}\nFileInputStream in = vfs.newInputStream(selectedPath);","handlingStrategy":"validation","validationCode":"if (vfs.isDirectory(path)) throw new IllegalArgumentException(\"Expected a file: \" + path);","typeGuard":null,"tryCatchPattern":"try {\n    FileInputStream in = vfs.newInputStream(path);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\"is not a file.\")) {\n        // treat as directory: list children instead\n    }\n}","preventionTips":["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"],"tags":["filesystem","virtual-fs","not-a-file"],"backgroundTag":"path-is-not-a-file","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}