MuntashirAkon/AppManager · error · UnsupportedOperationException

Invalid key ${key}

Error message

Invalid key ${key}

What it means

TargetSdkOption.test() compares a package's target SDK version against an int filter value using keys eq/le/ge. An unrecognized key hits the default branch and throws UnsupportedOperationException('Invalid key ...'), because no comparison can be made.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/filters/options/TargetSdkOption.java:47

    @Override
    public Map<String, Integer> getKeysWithType() {
        return mKeysWithType;
    }

    @NonNull
    @Override
    public TestResult test(@NonNull IFilterableAppInfo info, @NonNull TestResult result) {
        switch (key) {
            case KEY_ALL:
                return result.setMatched(true);
            case "eq":
                return result.setMatched(info.getTargetSdk() == intValue);
            case "le":
                return result.setMatched(info.getTargetSdk() <= intValue);
            case "ge":
                return result.setMatched(info.getTargetSdk() >= intValue);
            default:
                throw new UnsupportedOperationException("Invalid key " + key);
        }
    }

    @NonNull
    @Override
    public CharSequence toLocalizedString(@NonNull Context context) {
        SpannableStringBuilder sb = new SpannableStringBuilder("Target 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

  1. Verify the option's key and set it to one of eq, le, or ge
  2. Fix or migrate the persisted filter JSON to current key names
  3. Add the missing key case if a new comparison mode was intended

Example fix

// before
new TargetSdkOption("less_than", 28);
// after
new TargetSdkOption("le", 28);
Defensive patterns

Strategy: validation

Validate before calling

if (!"eq".equals(key) && !"le".equals(key) && !"ge".equals(key)) {
    throw new IllegalArgumentException("TargetSdk key must be eq/le/ge, got: " + key);
}

Type guard

boolean isTargetSdkKey(String k) { return "eq".equals(k) || "le".equals(k) || "ge".equals(k); }

Try / catch

try {
    include = targetSdkOption.test(appInfo);
} catch (UnsupportedOperationException e) {
    include = false;
    Log.w(TAG, "Invalid target-SDK filter key", e);
}

Prevention

When it happens

Trigger: Running test() with a TargetSdkOption whose key is not eq/le/ge — from corrupted, outdated, or mistyped filter definitions.

Common situations: Old filter files persisted before key renames; constructing options programmatically with a wrong key string.

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/66842398a02de0e9. Report an issue: GitHub.