MuntashirAkon/AppManager · error · BackupException

Misc restore is requested but the app isn't installed.

Error message

Misc restore is requested but the app isn't installed.

What it means

Thrown by restoreExtras when a misc/permissions restore was requested but the target application is not currently installed on the device. Misc rules (permissions and other app settings) can only be applied to an installed package, so the operation is aborted up front.

Solutions

  1. Install the application before running the restore, then retry the misc restore
  2. Uncheck/misc-disable the misc restore flag in the restore options
  3. Verify you are restoring for the correct user ID (work profile vs main user) where the app is installed
  4. If only app data should be restored, choose a data-only restore mode

Example fix

// before
RestoreOp.RestoreRequestFlags flags = new RestoreRequestFlags(true, true, true, true); // includes misc
new RestoreOp(context, backupItem, flags).runRestore();
// after
boolean appInstalled = isPackageInstalled(context, backupItem.getPackageName(), userId);
RestoreOp.RestoreRequestFlags flags = new RestoreRequestFlags(true, true, true, appInstalled /* skip misc if not installed */);
new RestoreOp(context, backupItem, flags).runRestore();
Defensive patterns

Strategy: validation

Validate before calling

try {
    pm.getPackageInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
    flags.skipMisc = true;
}

Try / catch

try {
    restoreOp.runRestore();
} catch (BackupException e) {
    if (e.getMessage().contains("app isn't installed")) {
        promptInstallAppThenRetry();
    } else throw e;
}

Prevention

When it happens

Trigger: Backup flags include restoring misc data (permissions etc.) but mIsInstalled is false — i.e. the package is not installed for mUserId when restoreExtras runs.

Common situations: Restoring a backup for an app that was uninstalled; restoring for a different user profile where the app isn't installed; asking for a full restore (including misc) instead of an app-only data restore.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java:625

        }
        // Decrypt data
        try {
            dataFiles = mBackupItem.decrypt(dataFiles);
        } catch (IOException e) {
            throw new BackupException("Failed to decrypt " + Arrays.toString(dataFiles), e);
        }
        // Restore data
        try (InputStream is = dataFiles[0].openInputStream()) {
            ParcelFileDescriptor fd = ParcelFileDescriptorUtil.pipeFrom(is);
            BackupCompat.adbRestore(mUserId, fd);
        } catch (Throwable th) {
            throw new BackupException("Failed to restore ADB data", th);
        }
    }

    private synchronized void restoreExtras() throws BackupException {
        if (!mIsInstalled) {
            throw new BackupException("Misc restore is requested but the app isn't installed.");
        }
        PseudoRules rules = new PseudoRules(mPackageName, mUserId);
        // Backward compatibility for restoring permissions
        loadMiscRules(rules);
        // Apply rules
        List<RuleEntry> entries = rules.getAll();
        AppOpsManagerCompat appOpsManager = new AppOpsManagerCompat();
        INotificationManager notificationManager = INotificationManager.Stub.asInterface(ProxyBinder.getService(Context.NOTIFICATION_SERVICE));
        boolean magiskHideAvailable = MagiskHide.available();
        boolean canModifyAppOpMode = SelfPermissions.canModifyAppOpMode();
        boolean canChangeNetPolicy = SelfPermissions.checkSelfOrRemotePermission(ManifestCompat.permission.MANAGE_NETWORK_POLICY);
        for (RuleEntry entry : entries) {
            try {
                switch (entry.type) {
                    case APP_OP:
                        if (canModifyAppOpMode) {
                            appOpsManager.setMode(Integer.parseInt(entry.name), mUid, mPackageName,
                                    ((AppOpRule) entry).getMode());

View on GitHub (pinned to 0152f468fc)