{"record":{"id":"2ff444d8a5881827","repo":"skylot/jadx","slug":"is-unknown-possible-values-are","errorCode":null,"errorMessage":"'{}' is unknown, possible values are: {}","messagePattern":"'(.+?)' is unknown, possible values are: (.+?)","errorType":"validation","errorClass":"JadxArgsValidateException","httpStatus":null,"severity":"error","filePath":"jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java","lineNumber":1066,"sourceCode":"\t\t\tsuper(CallGraphSaveMode::valueOf, CallGraphSaveMode::values);\n\t\t}\n\t}\n\n\tpublic abstract static class BaseEnumConverter<E extends Enum<E>> implements IStringConverter<E> {\n\t\tprivate final Function<String, E> parse;\n\t\tprivate final Supplier<E[]> values;\n\n\t\tpublic BaseEnumConverter(Function<String, E> parse, Supplier<E[]> values) {\n\t\t\tthis.parse = parse;\n\t\t\tthis.values = values;\n\t\t}\n\n\t\t@Override\n\t\tpublic E convert(String value) {\n\t\t\ttry {\n\t\t\t\treturn parse.apply(stringAsEnumName(value));\n\t\t\t} catch (Exception e) {\n\t\t\t\tthrow new JadxArgsValidateException(\n\t\t\t\t\t\t'\\'' + value + \"' is unknown, possible values are: \" + enumValuesString(values.get()));\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static String enumValuesString(Enum<?>[] values) {\n\t\treturn Stream.of(values)\n\t\t\t\t.map(v -> v.name().replace('_', '-').toLowerCase(Locale.ROOT))\n\t\t\t\t.collect(Collectors.joining(\", \"));\n\t}\n\n\tprivate static String stringAsEnumName(String value) {\n\t\t// inverse of enumValuesString conversion\n\t\treturn value.replace('-', '_').toUpperCase(Locale.ROOT);\n\t}\n}\n","sourceCodeStart":1048,"sourceCodeEnd":1083,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java#L1048-L1083","documentation":"Thrown by FieldNodeAdapter.read while deserializing a cached code annotation: it reads the declaring class name and short id that were persisted, then calls root.resolveRawClass(cls). If the class is absent from the current project the lookup returns null and the adapter aborts. It means the on-disk cache references a class that the loaded APK/jadx state no longer contains.","triggerScenarios":"Loading a persisted code-annotation cache (the per-project disk cache written by jadx-gui) whose entries were written against a different input. resolveRawClass fails because the APK was swapped, rebuilt, or proguard-mapped differently since the cache was written.","commonSituations":"Re-opening a project after the APK was updated/re-signed/obfuscated differently; switching jadx versions that resolve classes differently; the cache directory surviving an input change; loading a cache written on another machine against a different APK.","solutions":["Delete the jadx cache directory for the project and let it rebuild (fastest fix).","Ensure the APK opened is byte-identical to the one that produced the cache; if not, invalidate the cache.","Upgrade jadx; newer versions catch this and invalidate the cache instead of crashing.","Verify the APK path did not change under the same cache key."],"exampleFix":"// before\nClassNode clsNode = root.resolveRawClass(cls);\nif (clsNode == null) {\n    throw new RuntimeException(\"Class not found: \" + cls);\n}\n\n// after\nClassNode clsNode = root.resolveRawClass(cls);\nif (clsNode == null) {\n    // stale cache entry: signal caller to discard the on-disk cache and rebuild\n    throw new CacheInvalidatedException(\"Class not found: \" + cls);\n}","handlingStrategy":"validation","validationCode":"// Before deserializing a cached annotation referencing a class, confirm it still resolves:\nClassNode clsNode = root.resolveRawClass(cls);\nif (clsNode == null) {\n    // input changed since cache write: invalidate and rebuild rather than throw\n    invalidateCache();\n    return;\n}","typeGuard":null,"tryCatchPattern":"// Cache load layer: catch and discard the whole cache on a stale reference\ntry {\n    return adapter.read(in);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Class not found\")) {\n        LOG.warn(\"Stale cache, rebuilding: {}\", e.getMessage());\n        cacheDir.delete();\n        return null;\n    }\n    throw e;\n}","preventionTips":["Invalidate the jadx cache whenever the input APK changes (hash/key the cache by APK identity).","Do not share a cache across jadx versions.","Upgrade jadx so a class miss invalidates instead of crashing."],"tags":["cache","disk-adapter","field-node","stale-cache"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}