MuntashirAkon/AppManager · error · BackupException

APK files backup is requested but no source directory has be

Error message

APK files backup is requested but no source directory has been backed up.

What it means

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.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupOp.java:330

    private void backupApkFiles() throws BackupException {
        Path dataAppPath = OsEnvironment.getDataAppDirectory();
        final String sourceBackupFilePrefix = BackupUtils.getSourceFilePrefix(getExt(mMetadata.info.tarType));
        Path sourceDir = Paths.get(PackageUtils.getSourceDir(mApplicationInfo));
        if (dataAppPath.equals(sourceDir)) {
            // APK located inside /data/app directory
            // Backup only the apk file (no split apk support for this type of apk)
            try {
                sourceDir = sourceDir.findFile(mMetadata.metadata.apkName);
            } catch (FileNotFoundException e) {
                throw new BackupException(mMetadata.metadata.apkName + " not found at " + sourceDir);
            }
        }
        Path[] sourceFiles;
        try {
            sourceFiles = TarUtils.create(mMetadata.info.tarType, sourceDir, mBackupItem.getUnencryptedBackupPath(), sourceBackupFilePrefix,
                    /* language=regexp */ new String[]{".*\\.apk"}, null, null, false).toArray(new Path[0]);
        } catch (Throwable th) {
            throw new BackupException("APK files backup is requested but no source directory has been backed up.", th);
        }
        try {
            sourceFiles = mBackupItem.encrypt(sourceFiles);
        } catch (IOException e) {
            throw new BackupException("Failed to encrypt " + Arrays.toString(sourceFiles), e);
        }
        for (Path file : sourceFiles) {
            mChecksum.add(file.getName(), DigestUtils.getHexDigest(mMetadata.info.checksumAlgo, file));
        }
    }

    private void backupData() throws BackupException {
        for (int i = 0; i < mMetadata.metadata.dataDirs.length; ++i) {
            Path[] dataFiles;
            String backupDataDir = mMetadata.metadata.dataDirs[i];
            if (backupDataDir.equals(BackupManager.DATA_BACKUP_SPECIAL_ADB)) {
                // ADB backup
                dataFiles = backupAdb(i);

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Check the chained cause (tar/I/O error vs. no matches) for the root reason.
  2. Ensure App Manager has root/ADB access to read the app's source directory.
  3. Confirm the app's sourceDir exists and contains .apk files before backup.
  4. Retry without the APK-backup flag if only data backup is needed.

Example fix

// before
if (mBackupFlags.backupApkFiles()) { backupApkFiles(); } // crashes when source unreadable
// after
if (mBackupFlags.backupApkFiles() && new File(mPackageInfo.applicationInfo.sourceDir).canRead()) {
    backupApkFiles();
}
Defensive patterns

Strategy: validation

Validate before calling

String src = packageInfo.applicationInfo.sourceDir;
if (src == null || !new File(src).canRead()) { throw new IllegalStateException("Cannot read APK source: " + src); }

Type guard

boolean apksReadable(ApplicationInfo info) {
    return info != null && info.sourceDir != null && new File(info.sourceDir).canRead();
}

Try / catch

try {
    backupOp.runBackup(progress);
} catch (BackupException e) {
    if (e.getMessage().startsWith("APK files backup is requested")) {
        Log.e(TAG, "APK archive failed", e.getCause());
        fallbackToDataOnlyBackup();
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: App installed on unmounted external storage; source directory unreadable without root; instant apps or apps with no extractable APK path; filters excluding all APKs.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/e92cb932d382baa7. Report an issue: GitHub.