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
- Install the application before running the restore, then retry the misc restore
- Uncheck/misc-disable the misc restore flag in the restore options
- Verify you are restoring for the correct user ID (work profile vs main user) where the app is installed
- 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
- Always install the target app before restoring its backup
- Check the correct userId/profile when restoring
- Restrict restore flags to what is actually applicable
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
- Rules restore is requested but the app isn't installed.
- Android System (android) cannot be restored.
- Could not get backup files.
- Could not get crypto
- Could not read backup info. Possibly due to a malformed…
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)