MuntashirAkon/AppManager · error · UnsupportedOperationException
Invalid key ${key}
Error message
Invalid key ${key} What it means
MinSdkOption.test matches an application's minimum SDK against the configured comparison by switching on key ('eq', 'le', 'ge'). An unrecognized key reaches the default branch and throws UnsupportedOperationException 'Invalid key <key>'. The filter's comparison key is not a valid MinSdk operator.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/filters/options/MinSdkOption.java:53
}
@NonNull
@Override
public TestResult test(@NonNull IFilterableAppInfo info, @NonNull TestResult result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return result.setMatched(true);
}
switch (key) {
case KEY_ALL:
return result.setMatched(true);
case "eq":
return result.setMatched(info.getMinSdk() == intValue);
case "le":
return result.setMatched(info.getMinSdk() <= intValue);
case "ge":
return result.setMatched(info.getMinSdk() >= intValue);
default:
throw new UnsupportedOperationException("Invalid key " + key);
}
}
@NonNull
@Override
public CharSequence toLocalizedString(@NonNull Context context) {
SpannableStringBuilder sb = new SpannableStringBuilder("Minimum SDK");
switch (key) {
case KEY_ALL:
return sb.append(LangUtils.getSeparatorString()).append("any");
case "eq":
return sb.append(" = ").append(Integer.toString(intValue));
case "le":
return sb.append(" ≤ ").append(Integer.toString(intValue));
case "ge":
return sb.append(" ≥ ").append(Integer.toString(intValue));
default:
throw new UnsupportedOperationException("Invalid key " + key);View on GitHub (pinned to 0152f468fc)
Solutions
- Change the key in the filter config to 'eq', 'le', or 'ge'.
- Re-create the filter via the app UI.
- Update/downgrade App Manager so the key set matches the one that created the filter.
- Validate the key when constructing the option; fail fast with a clear message.
Example fix
// before
new MinSdkOption("min_sdk", "<=", 24);
// after
new MinSdkOption("min_sdk", "le", 24); Defensive patterns
Strategy: validation
Validate before calling
Set<String> VALID = Set.of("eq", "le", "ge");
if (!VALID.contains(option.getKey())) throw new IllegalArgumentException("Unsupported min_sdk key: " + option.getKey()); Type guard
boolean isValidKey(String k) { return "eq".equals(k) || "le".equals(k) || "ge".equals(k); } Try / catch
try { matched = option.test(info); } catch (UnsupportedOperationException e) { Log.w(TAG, e.getMessage()); matched = false; } Prevention
- Use the canonical operator keys eq/le/ge
- Validate keys at filter deserialization
- Avoid copying keys between different option types
- Test filters after app upgrades
When it happens
Trigger: Calling test() on a MinSdkOption whose key is not exactly 'eq', 'le', or 'ge' — typically from a deserialized filter file with a typo, a renamed key across versions, or an operator borrowed from another option type.
Common situations: Hand-edited filter JSON using '<' or '<=' instead of 'le'; copying a key from a different filter option (e.g. 'before'); filters shared between app versions with differing key sets.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/e57e0b7cd96df194.
Report an issue: GitHub.