{"record":{"id":"031363932872f3b6","repo":"MuntashirAkon/AppManager","slug":"data-restore-is-requested-but-the-app-isn-t-installed","errorCode":null,"errorMessage":"Data restore is requested but the app isn't installed.","messagePattern":"Data restore is requested but the app isn't installed\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":484,"sourceCode":"                String newFilename = Utils.replaceOnce(keyStoreFileName, String.valueOf(KEYSTORE_PLACEHOLDER), String.valueOf(mUid));\n                keyStorePath.findFile(keyStoreFileName).renameTo(newFilename);\n                Path targetFile = keyStorePath.findFile(newFilename);\n                // Restore file permission\n                Paths.chown(targetFile, uidGidPair.uid, uidGidPair.gid);\n                //noinspection OctalInteger\n                Paths.chmod(targetFile, 0600);\n            } catch (IOException | ErrnoException e) {\n                throw new BackupException(\"Failed to rename KeyStore files\", e);\n            }\n        }\n        Runner.runCommand(new String[]{\"restorecon\", \"-R\", keyStorePath.getFilePath()});\n    }\n\n    private void restoreData() throws BackupException {\n        // Data restore is requested: Data restore is only possible if the app is actually\n        // installed. So, check if it's installed first.\n        if (mPackageInfo == null) {\n            throw new BackupException(\"Data restore is requested but the app isn't installed.\");\n        }\n        if (!mRequestedFlags.skipSignatureCheck()) {\n            // Verify integrity of the data backups\n            String checksum;\n            for (int i = 0; i < mBackupMetadata.dataDirs.length; ++i) {\n                Path[] dataFiles = mBackupItem.getDataFiles(i);\n                if (dataFiles.length == 0) {\n                    throw new BackupException(\"Data restore is requested but there are no data files for index \" + i + \".\");\n                }\n                for (Path file : dataFiles) {\n                    checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, file);\n                    if (!checksum.equals(mChecksum.get(file.getName()))) {\n                        throw new BackupException(\"Data file verification failed for index \" + i + \".\" +\n                                \"\\nFile: \" + file +\n                                \"\\nFound: \" + checksum +\n                                \"\\nRequired: \" + mChecksum.get(file.getName()));\n                    }\n                }","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L466-L502","documentation":"restoreData requires the target app to actually be installed because data can only be restored into an existing package. If mPackageInfo is null (the package was not found / not installed for this user), this BackupException is thrown before any data work begins. It is an explicit precondition check, not an I/O failure.","triggerScenarios":"Calling the restore flow with data restore requested for a package that is not installed on the device/user; the package was uninstalled (even with keepData) before running restore; wrong userId so PackageInstaller cannot see the installed package.","commonSituations":"Restoring only-data backup onto a fresh device without first installing the APK; restoring for a work-profile user where the app is installed only in the main user; typo'd or stale package name in a scripted restore.","solutions":["Install the app (APK from the backup or store) before running the data restore.","Ensure the restore targets the correct userId where the app is installed (or install for that user).","If only app data exists in the backup, restore the APK part first or switch to a full (APK+data) restore.","Verify the package name spelling matches the installed package."],"exampleFix":"// before: attempting data-only restore for uninstalled app\nrestoreOp.runRestore(); // throws BackupException\n// after: guard in caller\nif (restoreOp.isDataRestoreRequested() && getInstalledPackageInfo(pkg, userId) == null) {\n    installApkFromBackup(pkg); // install first\n}\nrestoreOp.runRestore();","handlingStrategy":"validation","validationCode":"PackageInfo pi = getPackageManager().getPackageInfoAsUser(pkg, 0, userId);\nif (pi == null) throw new IllegalStateException(\"App must be installed before data restore: \" + pkg);\n","typeGuard":"boolean isInstalled(PackageInfo pi) { return pi != null && pi.applicationInfo != null; }","tryCatchPattern":"try { runRestore(); } catch (BackupException e) {\n    if (e.getMessage().contains(\"isn't installed\")) {\n        installApkFromBackupThenRetry(pkg);\n    } else throw e;\n}","preventionTips":["Install the APK before requesting a data-only restore.","Confirm the correct userId (main user vs. work profile).","Never uninstall the app between backup creation and restore.","In automation, assert package presence before invoking restore."],"tags":["android","backup","restore","package-not-installed"],"backgroundTag":"entity-not-found","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}