MuntashirAkon/AppManager · error · BackupException

Restore is requested without any flags.

Error message

Restore is requested without any flags.

What it means

BackupManager.restore() requires at least one backup flag (e.g. source, data, permissions) in RestoreOpOptions.flags. An empty flag set means nothing to restore, so the method refuses to proceed with a BackupException. This is an upfront argument-validation error.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupManager.java:100

            progressHandler.setProgressTextInterface(ProgressHandler.PROGRESS_PERCENT);
            progressHandler.postUpdate(max, 0f);
        }
        try (BackupOp backupOp = new BackupOp(options.packageName, options.flags, backupItem, options.userId)) {
            backupOp.runBackup(progressHandler);
            BackupUtils.putBackupToDbAndBroadcast(ContextUtils.getContext(), backupOp.getMetadata());
        }
    }

    /**
     * Restore a single backup for a given package belonging to the given package
     */
    public void restore(@NonNull RestoreOpOptions options, @Nullable ProgressHandler progressHandler)
            throws BackupException {
        if (options.packageName.equals("android")) {
            throw new BackupException("Android System (android) cannot be restored.");
        }
        if (options.flags.isEmpty()) {
            throw new BackupException("Restore is requested without any flags.");
        }
        BackupItems.BackupItem backupItem;
        try {
            if (options.relativeDir != null) {
                backupItem = BackupItems.findBackupItem(options.relativeDir);
            } else {
                // Use base backup
                Backup baseBackup = BackupUtils.retrieveBaseBackupFromDb(options.userId, options.packageName);
                if (baseBackup != null) {
                    backupItem = baseBackup.getItem();
                } else {
                    throw new BackupException("No base backup found.");
                }
            }
        } catch (IOException e) {
            throw new BackupException("Could not get backup files.", e);
        }
        if (progressHandler != null) {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Set the desired flags on RestoreOpOptions before calling restore(), e.g. backup flags for APK/data.
  2. If the caller should restore everything, pass the full flag set used by the UI defaults.
  3. Validate flags non-empty at the call site and surface a user-facing 'nothing selected' message instead of invoking restore.
  4. Catch BackupException to report the configuration problem.

Example fix

// before
RestoreOpOptions options = new RestoreOpOptions(pkg, userId); // flags empty
// after
RestoreOpOptions options = new RestoreOpOptions(pkg, userId,
    BackupFlags.FLAG_APP_SOURCE | BackupFlags.FLAG_APP_DATA);
Defensive patterns

Strategy: validation

Validate before calling

if (options.flags == null || options.flags.isEmpty()) {
    throw new IllegalArgumentException("Restore flags must not be empty");
}

Type guard

boolean hasRestoreFlags(RestoreOpOptions o) { return o.flags != null && !o.flags.isEmpty(); }

Try / catch

try {
    manager.restore(options, progress);
} catch (BackupException e) {
    if (e.getMessage().contains("without any flags")) { /* prompt user to select flags */ }
}

Prevention

When it happens

Trigger: Constructing RestoreOpOptions with flags left empty/null (default value) and calling restore(), restoreBackups(), or the testRestoreV4* helpers.

Common situations: Programmatically building restore options from user preferences where no checkbox was selected; forgetting to copy flag bitmasks when adapting sample code; deserializing options from storage where the flags field defaulted to 0.

Understand the failure class

Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.

Related errors


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