MuntashirAkon/AppManager · error · FileNotFoundException

Path does not exist.

Error message

Path  does not exist.

What it means

FileCache.getCachedFile throws FileNotFoundException when the given Path does not exist on the filesystem. The cache layer intentionally refuses to cache a non-existent source instead of silently creating an empty temp file. Callers must ensure the source path is valid before requesting a cached copy.

Solutions

  1. Check source.exists() before calling getCachedFile and handle the missing file gracefully
  2. Re-resolve or re-fetch the source path (e.g. re-query the SAF URI) since it may be stale
  3. Verify storage volume is mounted (Environment.getExternalStorageState) before use
  4. Wrap in try-catch FileNotFoundException and fall back to skipping the cache

Example fix

// before
File cached = fileCache.getCachedFile(sourcePath);
// after
if (sourcePath.exists()) {
    File cached = fileCache.getCachedFile(sourcePath);
} else {
    // re-resolve the URI or skip caching
}
Defensive patterns

Strategy: validation

Validate before calling

if (source == null || !source.exists()) {
    throw new FileNotFoundException("Path " + source + " does not exist.");
}

Type guard

static boolean isReadableFile(Path p) {
    return p != null && p.exists() && p.isFile() && p.canRead();
}

Try / catch

try {
    File cached = cache.getCachedFile(source);
} catch (FileNotFoundException e) {
    // re-resolve source or skip caching
}

Prevention

When it happens

Trigger: Calling getCachedFile(Path) with a path that was deleted, never created, is on unmounted storage, or whose string form is empty/malformed so exists() returns false.

Common situations: Caching a file picked from SAF whose underlying document was removed; referencing an app data file after the app was cleared; path on external storage that is not mounted; race where another process deletes the file between listing and caching.

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


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/0152eb35967d9de6. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/self/filecache/FileCache.java:78

    public void close() {
        mClosed = true;
        if (mSessionOnly) {
            deleteAll();
        }
    }

    @Override
    protected void finalize() {
        if (!mClosed) {
            close();
        }
    }

    @NonNull
    public File getCachedFile(@NonNull Path source) throws IOException {
        if (!source.exists()) {
            // No need for cache if the path is non-existent
            throw new FileNotFoundException("Path " + source + " does not exist.");
        }
        File tempFile = mFileCacheMap.get(source);
        if (tempFile == null || !tempFile.exists()) {
            String extension = source.getExtension();
            tempFile = File.createTempFile(source.getName() + "_", "." + (extension != null ? extension : "tmp"), mCacheDir);
            mFileCacheMap.put(source, tempFile);
        } else if (source.lastModified() > 0 && source.lastModified() < tempFile.lastModified()) {
            return tempFile;
        }
        IoUtils.copy(source, Paths.get(tempFile));
        return tempFile;
    }

    @NonNull
    public File getCachedFile(@NonNull InputStream is, @Nullable String extension) throws IOException {
        File tempFile = File.createTempFile("file_", "." + (extension != null ? extension : "tmp"), mCacheDir);
        mFileCache.add(tempFile);
        try (OutputStream os = new FileOutputStream(tempFile)) {

View on GitHub (pinned to 0152f468fc)