MuntashirAkon/AppManager · error · UnsupportedOperationException

Invalid key

Error message

Invalid key ${key}

What it means

InstalledOption.test() switches over the configured key (all/installed/not_installed/installed_before/installed_after); any other key hits the default branch and throws UnsupportedOperationException. The key should have been validated by setKeyValue(), so this means the key state is inconsistent with the class's switch.

Solutions

  1. Add a case for the key in InstalledOption.test()'s switch.
  2. Set keys only through setKeyValue() for early validation.
  3. Keep the key map and test() switch synchronized.

Example fix

// before
case "installed_after":
    return result.setMatched(installed && info.getFirstInstallTime() >= longValue);
default:
    throw new UnsupportedOperationException("Invalid key " + key);
// after
case "installed_after":
    return result.setMatched(installed && info.getFirstInstallTime() >= longValue);
case "new_key":
    return result.setMatched(/* logic */);
default:
    throw new UnsupportedOperationException("Invalid key " + key);
Defensive patterns

Strategy: validation

Validate before calling

if (!option.getKeysWithType().containsKey(option.getKey())) {
    throw new IllegalStateException("Unrecognized key: " + option.getKey());
}

Try / catch

try {
    result = option.test(info, result);
} catch (UnsupportedOperationException e) {
    Log.w(TAG, "Filter option key not supported", e);
    result.setMatched(false);
}

Prevention

When it happens

Trigger: A key present in InstalledOption's key map but missing a case in test()'s switch; direct modification of the protected `key` field; stale keys from hand-built Parcels or reflection.

Common situations: Adding a new install-related key without updating test(); forked builds with extra keys; deserialization of crafted data.

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


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/filters/options/InstalledOption.java:52

    }

    @NonNull
    @Override
    public TestResult test(@NonNull IFilterableAppInfo info, @NonNull TestResult result) {
        boolean installed = info.isInstalled();
        switch (key) {
            case KEY_ALL:
                return result.setMatched(true);
            case "installed":
                return result.setMatched(installed);
            case "uninstalled":
                return result.setMatched(!installed);
            case "installed_before":
                return result.setMatched(installed && info.getFirstInstallTime() <= longValue);
            case "installed_after":
                return result.setMatched(installed && info.getFirstInstallTime() >= longValue);
            default:
                throw new UnsupportedOperationException("Invalid key " + key);
        }
    }

    @NonNull
    @Override
    public CharSequence toLocalizedString(@NonNull Context context) {
        SpannableStringBuilder sb = new SpannableStringBuilder("Installed");
        switch (key) {
            case KEY_ALL:
                return sb.append(LangUtils.getSeparatorString()).append("any");
            case "installed":
                return "Installed apps";
            case "uninstalled":
                return "Uninstalled apps";
            case "installed_before":
                return sb.append(" before ").append(DateUtils.formatDateTime(context, longValue));
            case "installed_after":
                return sb.append(" after ").append(DateUtils.formatDateTime(context, longValue));

View on GitHub (pinned to 0152f468fc)