{"record":{"id":"aafa8cc265970160","repo":"MuntashirAkon/AppManager","slug":"destination-doesn-t-contain-any-apk-files","errorCode":null,"errorMessage":"Destination doesn't contain any APK files.","messagePattern":"Destination doesn't contain any APK files\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/OABConverter.java","lineNumber":216,"sourceCode":"            metadataV2.splitConfigs = ArrayUtils.emptyArray(String.class);\n            metadataV2.hasRules = false;\n            metadataV2.backupTime = jsonObject.getLong(\"lastBackupMillis\");\n            metadataV2.crypto = jsonObject.optBoolean(\"isEncrypted\") ? CryptoUtils.MODE_OPEN_PGP : CryptoUtils.MODE_NO_ENCRYPTION;\n            mSourceCryptoMode = metadataV2.crypto;\n            mSourceCrypto = CryptoUtils.setupCrypto(metadataV2);\n            metadataV2.apkName = new File(jsonObject.getString(\"sourceDir\")).getName();\n            // Flags\n            metadataV2.flags = new BackupFlags(BackupFlags.BACKUP_MULTIPLE);\n            int backupMode = jsonObject.optInt(\"backupMode\", MODE_UNSET);\n            if (backupMode == MODE_UNSET) {\n                throw new BackupException(\"Destination doesn't contain any backup.\");\n            }\n            if (backupMode == MODE_APK || backupMode == MODE_BOTH) {\n                if (mBackupLocation.hasFile(CryptoUtils.getAppropriateFilename(metadataV2.apkName,\n                        mSourceCryptoMode))) {\n                    metadataV2.flags.addFlag(BackupFlags.BACKUP_APK_FILES);\n                } else {\n                    throw new BackupException(\"Destination doesn't contain any APK files.\");\n                }\n            }\n            if (backupMode == MODE_DATA || backupMode == MODE_BOTH) {\n                boolean hasBackup = false;\n                if (mBackupLocation.hasFile(CryptoUtils.getAppropriateFilename(mPackageName + \".zip\",\n                        mSourceCryptoMode))) {\n                    metadataV2.flags.addFlag(BackupFlags.BACKUP_INT_DATA);\n                    hasBackup = true;\n                }\n                if (mBackupLocation.hasFile(EXTERNAL_FILES) && mBackupLocation.findFile(EXTERNAL_FILES).hasFile(\n                        CryptoUtils.getAppropriateFilename(mPackageName + \".zip\", mSourceCryptoMode))) {\n                    metadataV2.flags.addFlag(BackupFlags.BACKUP_EXT_DATA);\n                    hasBackup = true;\n                }\n                if (!hasBackup) {\n                    throw new BackupException(\"Destination doesn't contain any data files.\");\n                }\n                metadataV2.flags.addFlag(BackupFlags.BACKUP_CACHE);","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/OABConverter.java#L198-L234","documentation":"When the parsed backupMode is MODE_APK or MODE_BOTH, the converter expects the destination backup location to contain the APK file for the app (named via CryptoUtils.getAppropriateFilename of the apkName from the source log, honoring source crypto mode). If BackupLocation.hasFile() cannot find that file, the conversion cannot fulfill the APK part of the backup, so it throws. This keeps App Manager backups internally consistent: a backup flagged for APKs must actually contain them.","triggerScenarios":"In readLogFile(), backupMode == MODE_APK or MODE_BOTH, and mBackupLocation.hasFile(CryptoUtils.getAppropriateFilename(metadataV2.apkName, mSourceCryptoMode)) returns false at OABConverter.java:216 — the expected APK file (possibly encrypted-named) is absent from the backup directory.","commonSituations":"Data-only OAndBackup backups being converted as if they included APKs; the APK was deleted or cleaned from the backup folder; a mismatch between the apkName in the log and the actual file name on disk; crypto-mode mismatch so the expected (encrypted) file name differs from what's stored.","solutions":["Ensure the source backup directory contains the APK file whose name matches the \"apkName\" field in the log (e.g. base.apk).","Re-run the OAndBackup backup in APK or Both mode so the APK is present before converting.","If you only have a data backup, convert with backupMode set to MODE_DATA instead of MODE_APK/MODE_BOTH.","Check for naming/crypto mismatch: if the source backup is encrypted, the file on disk has the crypto-transformed name; verify mSourceCryptoMode matches the actual files."],"exampleFix":"// before: converting a data-only backup while log claims APK backup\n// backupMode: 0 (MODE_APK) but directory only holds com.example.zip\n\n// after: correct the mode in the log to match contents\n// \"backupMode\": 1 (MODE_DATA) — or restore the missing base.apk into the backup dir","handlingStrategy":"validation","validationCode":"String expectedApk = CryptoUtils.getAppropriateFilename(\n        log.getString(\"apkName\"), sourceCryptoMode);\nif (!backupLocation.hasFile(expectedApk)) {\n    throw new IllegalStateException(\"Missing APK in backup dir: \" + expectedApk);\n}","typeGuard":null,"tryCatchPattern":"try {\n    converter.convert(...);\n} catch (BackupException e) {\n    if (e.getMessage().contains(\"doesn't contain any APK files\")) {\n        Log.e(TAG, \"Backup dir lacks the APK; check apkName and crypto mode\", e);\n    }\n}","preventionTips":["Keep the APK together with the log file in the backup directory; do not prune base.apk.","Match the requested backupMode to the actual backup contents before converting.","Verify source crypto mode so encrypted filenames are computed correctly."],"tags":["android","backup","file-not-found","apk","conversion"],"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-14T11:17:12.474Z"}