MuntashirAkon/AppManager · error · UnsupportedOperationException
Invalid key ${key}
Error message
Invalid key ${key} What it means
BackupOption.test() evaluates a PackageInfo against the configured key; if key is not one of the recognized cases (has_backup, backups, with_flags, etc.) the default branch throws UnsupportedOperationException("Invalid key " + key). It signals that the option was constructed with a key it cannot evaluate.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/filters/options/BackupOption.java:162
if ((backup.flags & intValue) == intValue) {
matchedBackups.add(backup);
}
}
return result.setMatched(!matchedBackups.isEmpty())
.setMatchedBackups(matchedBackups);
}
case "without_flags": {
List<Backup> matchedBackups = new ArrayList<>();
for (Backup backup : backups) {
if ((backup.flags & intValue) != intValue) {
matchedBackups.add(backup);
}
}
return result.setMatched(!matchedBackups.isEmpty())
.setMatchedBackups(matchedBackups);
}
default:
throw new UnsupportedOperationException("Invalid key " + key);
}
}
@NonNull
@Override
public CharSequence toLocalizedString(@NonNull Context context) {
SpannableStringBuilder sb = new SpannableStringBuilder();
switch (key) {
case KEY_ALL:
return "Apps with or without backups";
case "backups":
return "Only the apps with backups";
case "no_backups":
return "only the apps without backups";
case "latest_backup":
return "Only the apps having the latest backups";
case "outdated_backup":View on GitHub (pinned to 0152f468fc)
Solutions
- Use only keys BackupOption's switch supports (e.g. "has_backup", "no_backup", "backup_allowed", "backups", "with_flags", "without_flags")
- Add the missing case to test() if a new key was introduced
- Clear or migrate saved filters that carry stale keys
- Validate user-chosen keys against the supported list before constructing the option
Example fix
// before
FilterOption opt = new BackupOption("backup", "backup_exists"); // unknown key
boolean m = opt.test(packageInfo).isMatched(); // throws
// after
FilterOption opt = new BackupOption("backup", "has_backup"); // supported key
boolean m = opt.test(packageInfo).isMatched(); Defensive patterns
Strategy: type-guard
Validate before calling
Set<String> VALID = Set.of("has_backup","no_backup","backup_allowed","backups","with_flags","without_flags"); if (!VALID.contains(key)) throw new IllegalArgumentException("Unsupported BackupOption key: " + key); Type guard
boolean isValidBackupKey(String key) { return key != null && Set.of("has_backup","no_backup","backup_allowed","backups","with_flags","without_flags").contains(key); } Try / catch
try { boolean matched = option.test(packageInfo).isMatched(); } catch (UnsupportedOperationException e) { matched = false; /* skip unrecognizable filter */ } Prevention
- Use shared key constants instead of raw strings
- Migrate or drop filters saved by older app versions before applying
- Keep test()/toLocalizedString() key sets aligned
- Validate exported filter JSON against the current schema on import
When it happens
Trigger: Constructing BackupOption with an unrecognized key string and then calling test() during app-list filtering; saved filter configurations containing keys from a different AppManager version; typos in data-driven filter setup.
Common situations: After upgrading AppManager, old stored filters reference renamed keys; developer adds a new key to another option class and reuses it here; programmatic filter construction with hardcoded wrong key strings.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Invalid key ${key}
- Invalid key ${key}
- Couldn't delete old file <inputFile>
- Could not delete <mBackupPath>
- Could not move <mTempBackupPath> to <mBackupPath>
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/205938566d601d36.
Report an issue: GitHub.