MuntashirAkon/AppManager · error · UnsupportedOperationException
Invalid key ${key}
Error message
Invalid key ${key} What it means
SignatureOption.test() evaluates whether a package's signing info matches a filter criterion by switching on the option's key (subject starts-with, ends-with, regex, sha256, etc.). If the key is unrecognized it throws UnsupportedOperationException('Invalid key ...'), since test() cannot decide a match for an unknown criterion.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/filters/options/SignatureOption.java:137
if (regexValue.matcher(subject).matches()) {
matchedSubjectLines.add(subject);
}
}
return result.setMatched(!matchedSubjectLines.isEmpty())
.setMatchedSubjectLines(matchedSubjectLines);
}
case "sha256": {
String[] sha256sums = info.getSignatureSha256Checksums();
for (int i = 0; i < sha256sums.length; ++i) {
if (sha256sums[i].equals(value)) {
return result.setMatched(true)
.setMatchedSubjectLines(Collections.singletonList(info.getSignatureSubjectLines()[i]));
}
}
return result.setMatched(false).setMatchedSubjectLines(Collections.emptyList());
}
default:
throw new UnsupportedOperationException("Invalid key " + key);
}
}
@NonNull
@Override
public CharSequence toLocalizedString(@NonNull Context context) {
SpannableStringBuilder sb = new SpannableStringBuilder("Signatures");
switch (key) {
case KEY_ALL:
return sb.append(LangUtils.getSeparatorString()).append("any");
case "no_signer":
return sb.append(LangUtils.getSeparatorString()).append("none");
case "with_lineage":
return sb.append(" with lineages");
case "without_lineage":
return sb.append(" without lineages");
case "with_source_stamp":
return sb.append(" with source stamps");View on GitHub (pinned to 0152f468fc)
Solutions
- Inspect the failing option's key and correct it to a supported key used in SignatureOption.test()
- Migrate/regenerate the persisted filter to the current key vocabulary
- Extend test() (and toLocalizedString) with the missing key if you intentionally added a new criterion
Example fix
// before
SignatureOption opt = new SignatureOption("subj_sw", value);
// after
SignatureOption opt = new SignatureOption("subject_starts_with", value); // supported key Defensive patterns
Strategy: validation
Validate before calling
Set<String> validKeys = Set.of("subject_starts_with","subject_ends_with","sub_regex","sha256");
if (!validKeys.contains(opt.getKey())) throw new IllegalArgumentException("Bad signature filter key: " + opt.getKey()); Try / catch
try {
matched = option.test(packageInfo);
} catch (UnsupportedOperationException e) {
matched = false;
Log.w(TAG, "Skipping filter with unknown key", e);
} Prevention
- Define key constants in one place shared by test() and toLocalizedString()
- Migrate persisted filters when key names change
- Test round-trip serialization of every filter type
When it happens
Trigger: Invoking test() on a SignatureOption whose key is not among the implemented case labels — typically from a stale or hand-crafted filter definition.
Common situations: Applying old saved filters after an upgrade that renamed keys; sharing filter rules between versions; typos in programmatically generated filters.
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/c5270bc2393cbab8.
Report an issue: GitHub.