skylot/jadx · error · JadxArgsValidateException
Unknown command: {}. Expected one of: {}
Error message
Unknown command: {}. Expected one of: {} What it means
Thrown by FieldNodeAdapter.read after the declaring class resolved successfully but clsNode.searchFieldByShortId(sign) returns null. The persisted field short id (name + signature hash) does not match any field on the class in the current APK, so the cached reference cannot be reattached. It indicates the class exists but its fields changed since the cache was written.
Source
Thrown at jadx-cli/src/main/java/jadx/cli/JadxCLICommands.java:30
public class JadxCLICommands {
private static final Map<String, ICommand> COMMANDS_MAP = new LinkedHashMap<>();
static {
JadxCLICommands.register(new CommandPlugins());
}
public static void register(ICommand command) {
COMMANDS_MAP.put(command.name(), command);
}
public static void append(JCommander.Builder builder) {
COMMANDS_MAP.forEach(builder::addCommand);
}
public static boolean process(JCommanderWrapper jcw, JCommander jc, String parsedCommand) {
ICommand command = COMMANDS_MAP.get(parsedCommand);
if (command == null) {
throw new JadxArgsValidateException("Unknown command: " + parsedCommand
+ ". Expected one of: " + COMMANDS_MAP.keySet());
}
JCommander subCommander = jc.getCommands().get(parsedCommand);
command.process(jcw, subCommander);
return true;
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Delete the project's jadx cache directory so annotations are recomputed from the current APK.
- Confirm the input APK is unchanged since the cache was generated; if it changed, treat the cache as invalid.
- Upgrade jadx so a field miss invalidates the entry instead of throwing.
- If fields are intentionally volatile, disable the on-disk annotation cache.
Example fix
// before
FieldNode fieldNode = clsNode.searchFieldByShortId(sign);
if (fieldNode == null) {
throw new RuntimeException("Field not found: " + cls + "." + sign);
}
// after
FieldNode fieldNode = clsNode.searchFieldByShortId(sign);
if (fieldNode == null) {
throw new CacheInvalidatedException("Field not found: " + cls + "." + sign);
} Defensive patterns
Strategy: validation
Validate before calling
// After resolving the class, confirm the field short id still exists:
FieldNode fieldNode = clsNode.searchFieldByShortId(sign);
if (fieldNode == null) {
invalidateCache(); // field set changed since write
return;
} Try / catch
try {
return adapter.read(in);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Field not found")) {
LOG.warn("Stale cache entry, rebuilding: {}", e.getMessage());
cacheDir.delete();
return null;
}
throw e;
} Prevention
- Clear the cache after rebuilding or re-obfuscating an APK.
- Key the cache by APK content hash so a changed field set triggers a clean rebuild.
- Prefer letting jadx recompute annotations over reusing a cache from a different build.
When it happens
Trigger: Cache deserialization reaches a field whose short id no longer matches: the class was kept but a field was renamed, retyped, added or removed between the cache-write APK and the currently loaded APK. searchFieldByShortId fails and the read aborts.
Common situations: APK recompiled with a different proguard mapping; field renamed by an optimizer; jadx version change that alters short-id computation; partial cache reuse after editing the input.
Related errors
- '{}' is unknown, possible values are: {}
- Input class not found: {}
- Failed to get inputs hash for plugin: {}
- Failed to write metadata file
- Failed to parse code annotations
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/9480824af6f2fb3a.
Report an issue: GitHub.