MuntashirAkon/AppManager · error · FileNotFoundException

FS Root not found.

Error message

FS Root not found.

What it means

ScannerViewModel.getUriFromClassName resolves the virtual filesystem root for the DEX VFS id created during scanning. If VirtualFileSystem.getFsRoot returns null (the VFS was closed or never mounted), it throws FileNotFoundException("FS Root not found.").

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/scanner/ScannerViewModel.java:213

        return mApkUri;
    }

    public void setApkUri(@NonNull Uri apkUri) {
        mApkUri = apkUri;
    }

    public List<String> getAllClasses() {
        return mAllClasses;
    }

    public Collection<String> getNativeLibraries() {
        return mNativeLibraries;
    }

    public Uri getUriFromClassName(String className) throws FileNotFoundException {
        Path fsRoot = VirtualFileSystem.getFsRoot(mDexVfsId);
        if (fsRoot == null) {
            throw new FileNotFoundException("FS Root not found.");
        }
        return fsRoot.findFile(className.replace('.', '/') + ".smali").getUri();
    }

    @WorkerThread
    private void cacheFileIfRequired() {
        // Test if this path is readable
        if (mApkFile == null || !FileUtils.canReadUnprivileged(mApkFile)) {
            // Not readable, cache the file
            try {
                mApkFile = mFileCache.getCachedFile(Paths.get(mApkUri));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @WorkerThread

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Re-run the scan (or reload the APK) so the virtual filesystem is mounted before requesting a class URI.
  2. Check VirtualFileSystem.getFsRoot(vfsId) != null before calling and re-initialize if null.
  3. Keep the ViewModel alive/scoped to the activity lifecycle so mDexVfsId and the VFS are not cleared prematurely.

Example fix

// before
Uri uri = viewModel.getUriFromClassName(className);
// after
Path root = VirtualFileSystem.getFsRoot(viewModel.getDexVfsId());
if (root == null) {
    viewModel.loadApk(apkUri); // re-mount VFS
}
Uri uri = viewModel.getUriFromClassName(className);
Defensive patterns

Strategy: try-catch

Validate before calling

Path root = VirtualFileSystem.getFsRoot(dexVfsId);
if (root == null) {
    throw new IllegalStateException("Scanner VFS not mounted; re-run the scan first.");
}

Try / catch

try {
    Uri uri = viewModel.getUriFromClassName(className);
} catch (FileNotFoundException e) {
    promptRescan(); // VFS root gone; re-load the APK
}

Prevention

When it happens

Trigger: Calling getUriFromClassName after the scanner's ViewModel cleared mDexVfsId / closed the VFS, or before the APK was successfully loaded, or after process death recreated the ViewModel without the VFS.

Common situations: Clicking a class in the scanner UI after the scan was cleared; configuration change/ViewModel recreation losing the VFS id; opening results in a stale fragment.

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/5860fc4e640c7140. Report an issue: GitHub.