MuntashirAkon/AppManager · error · IllegalArgumentException

Invalid backup name

Error message

Invalid backup name 

What it means

getRealBackupName() parses a backup name that may carry a user-id suffix (name_userid). If the segment before the first underscore is not digits-only, the name is considered malformed and an IllegalArgumentException 'Invalid backup name <name>' is thrown.

Solutions

  1. Rename the backup so any underscore follows a numeric user id (e.g. '0_myapp'), or remove underscores from the name
  2. Pass the backup name without a user-id suffix if a single user is targeted
  3. Validate the backup name format before calling getRealBackupName

Example fix

// before
String real = BackupUtils.getRealBackupName("my_backup"); // throws
// after
String real = BackupUtils.getRealBackupName("0_my_backup"); // user 0, name 'my_backup'
Defensive patterns

Strategy: validation

Validate before calling

static void requireValidBackupName(String name) {
    if (name == null || name.isEmpty()) throw new IllegalArgumentException("empty backup name");
    int us = name.indexOf('_');
    if (us > 0 && !TextUtils.isDigitsOnly(name.substring(0, us)))
        throw new IllegalArgumentException("name must be '<userid>_<name>' or contain no underscore");
}

Type guard

static boolean isValidBackupName(String name) {
    if (name == null || name.isEmpty()) return false;
    int us = name.indexOf('_');
    return us <= 0 || TextUtils.isDigitsOnly(name.substring(0, us));
}

Try / catch

try {
    String real = BackupUtils.getRealBackupName(name);
} catch (IllegalArgumentException e) {
    Toast.makeText(ctx, "Invalid backup name: " + name, Toast.LENGTH_LONG).show();
}

Prevention

When it happens

Trigger: Calling getRealBackupName with a backup name containing an underscore whose prefix is not a numeric user handle (e.g. 'my_backup' or 'foo_1_bar' where prefix 'foo' is non-numeric) and no earlier branch matched.

Common situations: User-supplied backup names containing underscores in the backup name itself; restoring backups created by other tools with different naming conventions; typos when passing backup names on the CLI.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupUtils.java:122

    @Nullable
    public static String getRealBackupName(int backupVersion, @Nullable String backupNameWithUserId) {
        if (backupVersion >= 5) {
            return backupNameWithUserId;
        } else {
            // v4 or earlier backup: {userid}[_{backup_name}]
            if (backupNameWithUserId == null || TextUtils.isDigitsOnly(backupNameWithUserId)) {
                // It's only a user ID
                return null;
            } else {
                int firstUnderscore = backupNameWithUserId.indexOf('_');
                if (firstUnderscore != -1) {
                    // Found an underscore
                    String userHandle = backupNameWithUserId.substring(0, firstUnderscore);
                    if (TextUtils.isDigitsOnly(userHandle)) {
                        return backupNameWithUserId.substring(firstUnderscore + 1);
                    }
                }
                throw new IllegalArgumentException("Invalid backup name " + backupNameWithUserId);
            }
        }
    }

    public static String getReadableTarType(@TarUtils.TarType String tarType) {
        int i = ArrayUtils.indexOf(TAR_TYPES, tarType);
        if (i == -1) {
            return "GZip";
        }
        return TAR_TYPES_READABLE[i];
    }

    @WorkerThread
    @NonNull
    public static HashMap<String, Backup> storeAllAndGetLatestBackupMetadata() {
        AppDb appDb = new AppDb();
        HashMap<String, Backup> backupMetadata = new HashMap<>();
        HashMap<String, List<BackupMetadataV5>> allBackupMetadata = getAllMetadata();

View on GitHub (pinned to 0152f468fc)