{"record":{"id":"c6a2a7e7b04029de","repo":"MuntashirAkon/AppManager","slug":"source-restore-is-requested-but-there-are-no-source-files","errorCode":null,"errorMessage":"Source restore is requested but there are no source files.","messagePattern":"Source restore is requested but there are no source files\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":281,"sourceCode":"                throw new BackupException(\"Master key existed when the checksum was made but now it doesn't.\");\n        }\n        if (oldChecksum == null) {\n            throw new BackupException(\"Master key exists but it didn't exist when the backup was made.\");\n        }\n        String newChecksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, masterKey.getContentAsString().getBytes());\n        if (!newChecksum.equals(oldChecksum)) {\n            throw new BackupException(\"Checksums for master key did not match.\");\n        }\n    }\n\n    private void restoreApkFiles() throws BackupException {\n        if (!mBackupFlags.backupApkFiles()) {\n            throw new BackupException(\"APK restore is requested but backup doesn't contain any source files.\");\n        }\n        Path[] backupSourceFiles = mBackupItem.getSourceFiles();\n        if (backupSourceFiles.length == 0) {\n            // No source backup found\n            throw new BackupException(\"Source restore is requested but there are no source files.\");\n        }\n        boolean isVerified = true;\n        if (mPackageInfo != null) {\n            // Check signature of the installed app\n            List<String> certChecksumList = Arrays.asList(PackageUtils.getSigningCertChecksums(mBackupInfo.checksumAlgo, mPackageInfo, false));\n            String[] certChecksums = BackupItems.Checksum.getCertChecksums(mChecksum);\n            for (String checksum : certChecksums) {\n                if (certChecksumList.contains(checksum)) continue;\n                isVerified = false;\n                if (!mRequestedFlags.skipSignatureCheck()) {\n                    throw new BackupException(\"Signing info verification failed.\" +\n                            \"\\nInstalled: \" + certChecksumList +\n                            \"\\nBackup: \" + Arrays.toString(certChecksums));\n                }\n            }\n        }\n        if (!mRequestedFlags.skipSignatureCheck()) {\n            String checksum;","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L263-L299","documentation":"After confirming APK restore was requested, restoreApkFiles() fetches the actual source (APK) files from the backup via mBackupItem.getSourceFiles(). If the returned array is empty, the backup directory contains no source archive despite the flags claiming APK backup, and this BackupException is thrown — the backup set is incomplete.","triggerScenarios":"mBackupFlags.backupApkFiles() is true but mBackupItem.getSourceFiles() returns a zero-length array during a restore.","commonSituations":"The source.tar(.gz) file was deleted or lost while copying/backing up the backup folder; an interrupted backup wrote flags/metadata but failed to write the source archive; partial backup restore from cloud storage where large files were skipped.","solutions":["Check the backup directory for the source archive file; if missing, re-copy the complete backup set from its origin.","Re-create the backup, ensuring the backup completes without interruption before restoring.","Restore without APK restore enabled and install the app from another source if only data can be restored.","Verify storage access/mount: sometimes the file exists but the backup path is wrong or not fully mounted, making getSourceFiles() see nothing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm source files exist before restore:\nPath[] sources = backupItem.getSourceFiles();\nif (sources.length == 0) {\n    // backup incomplete: re-copy full backup set before invoking restore\n}","typeGuard":null,"tryCatchPattern":"try { restoreOp.runRestore(); } catch (BackupException e) {\n    if (e.getMessage().contains(\"there are no source files\")) {\n        // prompt user to restore the missing source archive or skip APK restore\n    }\n}","preventionTips":["Verify backup completeness (all expected files present) right after backup and after any transfer.","Avoid interrupting backups mid-write; check the backup result status.","Store backup sets in stable storage, not on removable media prone to corruption."],"tags":["android","backup","missing-files","apk"],"backgroundTag":"resource-not-found","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}