MuntashirAkon/AppManager · warning · PackageManager.NameNotFoundException

Package not installed

Error message

Package not installed

What it means

In the non-external-APK branch of package loading, the ViewModel uses mInstalledPackageInfo fetched earlier with MATCH_UNINSTALLED_PACKAGES. If that cached info is null — meaning no package entry exists even as an uninstalled/data-only record for the user — it throws PackageManager.NameNotFoundException('Package not installed'). The catch marks mIsPackageExist=false and posts that to the UI.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/details/AppDetailsViewModel.java:1144

                // All signatures are fetched using PackageUtils where a fallback method is used in case the PackageInfo
                // didn't load any signature. So, we should be safe from any harm.
                mPackageInfo = mPackageManager.getPackageArchiveInfo(mApkPath, PackageManager.GET_PERMISSIONS
                        | PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS | PackageManager.GET_PROVIDERS
                        | PackageManager.GET_SERVICES | MATCH_DISABLED_COMPONENTS | PackageManager.GET_CONFIGURATIONS
                        | PackageManager.GET_SHARED_LIBRARY_FILES | PackageManager.GET_URI_PERMISSION_PATTERNS
                        | PackageManager.GET_META_DATA);
                if (mPackageInfo == null) {
                    throw new PackageManager.NameNotFoundException("Package cannot be parsed");
                }
                if (mInstalledPackageInfo == null) {
                    Log.d(TAG, "%s not installed for user %d", mPackageName, mUserId);
                }
                mPackageInfo.applicationInfo.sourceDir = mApkPath;
                mPackageInfo.applicationInfo.publicSourceDir = mApkPath;
            } else {
                mPackageInfo = mInstalledPackageInfo;
                if (mPackageInfo == null) {
                    throw new PackageManager.NameNotFoundException("Package not installed");
                }
            }
            mIsPackageExistLiveData.postValue(mIsPackageExist = true);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, e);
            mIsPackageExistLiveData.postValue(mIsPackageExist = false);
        } catch (Throwable e) {
            Log.e(TAG, e);
        } finally {
            mPackageChanged.postValue(true);
        }
    }

    @WorkerThread
    @Nullable
    private PackageInfo getPackageInfoInternal() {
        try {
            mPackageInfoWatcher.await();

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Verify installation with pm.getPackageInfo(name, 0) before opening details
  2. Query the correct userId (e.g. use UserHandleCompat for the profile where the app is installed)
  3. Handle the ViewModel's mIsPackageExist LiveData=false state gracefully in the UI
  4. Refresh/re-check if a race with uninstall is possible

Example fix

// before
viewModel.setPackage(stalePkg, userId); // NameNotFoundException
// after
try {
    pm.getPackageInfoAsUser(stalePkg, 0, userId);
    viewModel.setPackage(stalePkg, userId);
} catch (PackageManager.NameNotFoundException e) {
    navigateBackWithMessage("Package not installed for this user");
}
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    pm.getPackageInfoAsUser(pkg, 0, userId);
    boolean installed = true;
} catch (PackageManager.NameNotFoundException e) { boolean installed = false; }

Type guard

boolean isInstalledForUser(PackageManager pm, String pkg, int userId) {
    try { pm.getPackageInfoAsUser(pkg, 0, userId); return true; }
    catch (PackageManager.NameNotFoundException e) { return false; }
}

Try / catch

try {
    viewModel.setPackage(pkg, userId);
} catch (PackageManager.NameNotFoundException e) {
    // observe viewModel.getIsPackageExist() == false and show 'not installed' UI
}

Prevention

When it happens

Trigger: Calling the ViewModel's package-load path for a package name that isn't installed at all for mUserId: never installed, fully uninstalled without data, or wrong userId queried; also if the earlier mInstalledPackageInfo lookup failed (e.g. the 293 error path reset it to null).

Common situations: Opening details for a stale package name from a shortcut/history; querying a work-profile-only app from the main user; race where app is uninstalled between listing and opening details.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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