{"record":{"id":"e92cb932d382baa7","repo":"MuntashirAkon/AppManager","slug":"apk-files-backup-is-requested-but-no-source-directory-has","errorCode":null,"errorMessage":"APK files backup is requested but no source directory has been backed up.","messagePattern":"APK files backup is requested but no source directory has been backed up\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupOp.java","lineNumber":330,"sourceCode":"    private void backupApkFiles() throws BackupException {\n        Path dataAppPath = OsEnvironment.getDataAppDirectory();\n        final String sourceBackupFilePrefix = BackupUtils.getSourceFilePrefix(getExt(mMetadata.info.tarType));\n        Path sourceDir = Paths.get(PackageUtils.getSourceDir(mApplicationInfo));\n        if (dataAppPath.equals(sourceDir)) {\n            // APK located inside /data/app directory\n            // Backup only the apk file (no split apk support for this type of apk)\n            try {\n                sourceDir = sourceDir.findFile(mMetadata.metadata.apkName);\n            } catch (FileNotFoundException e) {\n                throw new BackupException(mMetadata.metadata.apkName + \" not found at \" + sourceDir);\n            }\n        }\n        Path[] sourceFiles;\n        try {\n            sourceFiles = TarUtils.create(mMetadata.info.tarType, sourceDir, mBackupItem.getUnencryptedBackupPath(), sourceBackupFilePrefix,\n                    /* language=regexp */ new String[]{\".*\\\\.apk\"}, null, null, false).toArray(new Path[0]);\n        } catch (Throwable th) {\n            throw new BackupException(\"APK files backup is requested but no source directory has been backed up.\", th);\n        }\n        try {\n            sourceFiles = mBackupItem.encrypt(sourceFiles);\n        } catch (IOException e) {\n            throw new BackupException(\"Failed to encrypt \" + Arrays.toString(sourceFiles), e);\n        }\n        for (Path file : sourceFiles) {\n            mChecksum.add(file.getName(), DigestUtils.getHexDigest(mMetadata.info.checksumAlgo, file));\n        }\n    }\n\n    private void backupData() throws BackupException {\n        for (int i = 0; i < mMetadata.metadata.dataDirs.length; ++i) {\n            Path[] dataFiles;\n            String backupDataDir = mMetadata.metadata.dataDirs[i];\n            if (backupDataDir.equals(BackupManager.DATA_BACKUP_SPECIAL_ADB)) {\n                // ADB backup\n                dataFiles = backupAdb(i);","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupOp.java#L312-L348","documentation":"backupApkFiles() archives all *.apk files from the source directory via TarUtils.create(); any Throwable from that call is wrapped in this BackupException. It means the APK backup flag was requested but zero APK files were produced — nothing was archived into the backup.","triggerScenarios":"TarUtils.create(...) throws (sourceDir unreadable, no matching .apk files, tar I/O error) so sourceFiles ends up empty or the call throws before producing output.","commonSituations":"App installed on unmounted external storage; source directory unreadable without root; instant apps or apps with no extractable APK path; filters excluding all APKs.","solutions":["Check the chained cause (tar/I/O error vs. no matches) for the root reason.","Ensure App Manager has root/ADB access to read the app's source directory.","Confirm the app's sourceDir exists and contains .apk files before backup.","Retry without the APK-backup flag if only data backup is needed."],"exampleFix":"// before\nif (mBackupFlags.backupApkFiles()) { backupApkFiles(); } // crashes when source unreadable\n// after\nif (mBackupFlags.backupApkFiles() && new File(mPackageInfo.applicationInfo.sourceDir).canRead()) {\n    backupApkFiles();\n}","handlingStrategy":"validation","validationCode":"String src = packageInfo.applicationInfo.sourceDir;\nif (src == null || !new File(src).canRead()) { throw new IllegalStateException(\"Cannot read APK source: \" + src); }","typeGuard":"boolean apksReadable(ApplicationInfo info) {\n    return info != null && info.sourceDir != null && new File(info.sourceDir).canRead();\n}","tryCatchPattern":"try {\n    backupOp.runBackup(progress);\n} catch (BackupException e) {\n    if (e.getMessage().startsWith(\"APK files backup is requested\")) {\n        Log.e(TAG, \"APK archive failed\", e.getCause());\n        fallbackToDataOnlyBackup();\n    }\n}","preventionTips":["Verify sourceDir readability (root/ADB) before APK backups.","Exclude instant apps and apps on unmounted storage from batch backups.","Check the chained cause to distinguish I/O errors from zero-match results.","Drop the APK flag for data-only backups of unreadable sources."],"tags":["android","backup","apk","tar"],"backgroundTag":"file-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"}