MuntashirAkon/AppManager · error · BackupException

Destination doesn't contain any backup.

Error message

Destination doesn't contain any backup.

What it means

OABConverter parses an OAndBackup-style log file to rebuild backup metadata. The log's "backupMode" field is read with jsonObject.optInt("backupMode", MODE_UNSET); if the key is absent or unreadable, backupMode stays MODE_UNSET and the converter refuses to continue because it cannot tell whether the source backup contains APKs, data, or both. This is a hard precondition: without a known backup mode the conversion would produce an incomplete or wrong App Manager backup.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/OABConverter.java:209

            JSONObject jsonObject = new JSONObject(jsonString);
            metadataV2.label = jsonObject.getString("label");
            metadataV2.packageName = jsonObject.getString("packageName");
            metadataV2.versionName = jsonObject.getString("versionName");
            metadataV2.versionCode = jsonObject.getInt("versionCode");
            metadataV2.isSystem = jsonObject.optBoolean("isSystem");
            metadataV2.isSplitApk = false;
            metadataV2.splitConfigs = ArrayUtils.emptyArray(String.class);
            metadataV2.hasRules = false;
            metadataV2.backupTime = jsonObject.getLong("lastBackupMillis");
            metadataV2.crypto = jsonObject.optBoolean("isEncrypted") ? CryptoUtils.MODE_OPEN_PGP : CryptoUtils.MODE_NO_ENCRYPTION;
            mSourceCryptoMode = metadataV2.crypto;
            mSourceCrypto = CryptoUtils.setupCrypto(metadataV2);
            metadataV2.apkName = new File(jsonObject.getString("sourceDir")).getName();
            // Flags
            metadataV2.flags = new BackupFlags(BackupFlags.BACKUP_MULTIPLE);
            int backupMode = jsonObject.optInt("backupMode", MODE_UNSET);
            if (backupMode == MODE_UNSET) {
                throw new BackupException("Destination doesn't contain any backup.");
            }
            if (backupMode == MODE_APK || backupMode == MODE_BOTH) {
                if (mBackupLocation.hasFile(CryptoUtils.getAppropriateFilename(metadataV2.apkName,
                        mSourceCryptoMode))) {
                    metadataV2.flags.addFlag(BackupFlags.BACKUP_APK_FILES);
                } else {
                    throw new BackupException("Destination doesn't contain any APK files.");
                }
            }
            if (backupMode == MODE_DATA || backupMode == MODE_BOTH) {
                boolean hasBackup = false;
                if (mBackupLocation.hasFile(CryptoUtils.getAppropriateFilename(mPackageName + ".zip",
                        mSourceCryptoMode))) {
                    metadataV2.flags.addFlag(BackupFlags.BACKUP_INT_DATA);
                    hasBackup = true;
                }
                if (mBackupLocation.hasFile(EXTERNAL_FILES) && mBackupLocation.findFile(EXTERNAL_FILES).hasFile(
                        CryptoUtils.getAppropriateFilename(mPackageName + ".zip", mSourceCryptoMode))) {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Check the source log file and ensure it contains a numeric "backupMode" entry (0/1/2 per OAndBackup's MODE_APK/MODE_DATA/MODE_BOTH convention).
  2. Re-create the backup with the original OAndBackup app so a fresh, complete log file is generated.
  3. If the log is hand-edited or migrated, add the missing "backupMode" key with the correct value instead of leaving it absent.
  4. Verify you are passing the correct log file (e.g. the per-package log, not a global index) to OABConverter.convert().

Example fix

// before: converting a log file that lacks the field
// { "packageName": "com.example", "apkName": "base.apk" }

// after: fix the source log JSON
// { "packageName": "com.example", "apkName": "base.apk", "backupMode": 2 }
Defensive patterns

Strategy: validation

Validate before calling

JSONObject log = readLogJson(logFile);
if (!log.has("backupMode") || log.optInt("backupMode", MODE_UNSET) == MODE_UNSET) {
    throw new IllegalArgumentException(logFile + " has no valid backupMode; cannot convert");
}

Type guard

static boolean hasBackupMode(JSONObject log) {
    return log.has("backupMode") && log.optInt("backupMode", Integer.MIN_VALUE) != Integer.MIN_VALUE;
}

Try / catch

try {
    converter.convert(...);
} catch (BackupException e) {
    if (e.getMessage().contains("doesn't contain any backup")) {
        Log.e(TAG, "Log file missing backupMode: inspect " + logFile, e);
    }
}

Prevention

When it happens

Trigger: readLogFile() (called from convert()) encounters a log JSON object where key "backupMode" is missing, or its value parses to MODE_UNSET, i.e. jsonObject.optInt("backupMode", MODE_UNSET) returns MODE_UNSET at OABConverter.java:209.

Common situations: Converting an OAndBackup log written by an older app version that did not record backupMode; a corrupted or truncated log file where the backupMode entry was lost; hand-edited log files; pointing the converter at a metadata/log file of a different format that lacks this key.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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