skylot/jadx · error · JadxArgsValidateException
Input class can't be saved by current jadx settings (marked
Error message
Input class can't be saved by current jadx settings (marked as DONT_GENERATE)
What it means
Thrown by RuntimeType.fromJdwpTag(int tag) when a JDWP value tag from the device does not match any of the sixteen standard JDWP.Tag constants handled by the switch (ARRAY, BYTE, CHAR, OBJECT, FLOAT, DOUBLE, INT, LONG, SHORT, VOID, BOOLEAN, STRING, THREAD, THREAD_GROUP, CLASS_LOADER, CLASS_OBJECT). All well-formed JDWP tags are covered, so reaching the default means the device sent a non-standard tag value or the byte stream is misaligned/corrupt. It is a protocol-level surprise from the debugged runtime.
Source
Thrown at jadx-cli/src/main/java/jadx/cli/SingleClassMode.java:40
public static boolean process(JadxDecompiler jadx, JadxCLIArgs cliArgs) {
String singleClass = cliArgs.getSingleClass();
String singleClassOutput = cliArgs.getSingleClassOutput();
if (singleClass == null && singleClassOutput == null) {
return false;
}
ClassNode clsForProcess;
if (singleClass != null) {
clsForProcess = jadx.getRoot().resolveClass(singleClass);
if (clsForProcess == null) {
clsForProcess = jadx.getRoot().getClasses().stream()
.filter(cls -> cls.getClassInfo().getAliasFullName().equals(singleClass))
.findFirst().orElse(null);
}
if (clsForProcess == null) {
throw new JadxArgsValidateException("Input class not found: " + singleClass);
}
if (clsForProcess.contains(AFlag.DONT_GENERATE)) {
throw new JadxArgsValidateException("Input class can't be saved by current jadx settings (marked as DONT_GENERATE)");
}
if (clsForProcess.isInner()) {
clsForProcess = clsForProcess.getTopParentClass();
LOG.warn("Input class is inner, parent class will be saved: {}", clsForProcess.getFullName());
}
} else {
// singleClassOutput is set
// expect only one class to be loaded
List<ClassNode> classes = jadx.getRoot().getClasses().stream()
.filter(c -> !c.isInner() && !c.contains(AFlag.DONT_GENERATE))
.collect(Collectors.toList());
int size = classes.size();
if (size == 1) {
clsForProcess = classes.get(0);
} else {
throw new JadxArgsValidateException("Found " + size + " classes, single class output can't be used");
}
}View on GitHub (pinned to e738a26571)
Solutions
- Try debugging on a stock Android device/emulator image whose JDWP tags conform to the spec.
- Upgrade jadx and its bundled jdwp library; newer versions may handle additional tags.
- Verify the ID sizes negotiated in initJDWP are correct for the target (a wrong field size desynchronizes every subsequent tag read).
- If you control the code, make fromJdwpTag return null and have callers skip the value rather than abort the debug session.
Example fix
// before
default:
throw new SmaliDebuggerException("Unexpected value: " + tag);
// after
default:
LOG.warn("Unknown JDWP value tag: {}", tag);
return null; // caller skips this value instead of killing the session Defensive patterns
Strategy: validation
Validate before calling
// Validate the tag is one JDWP actually defines before calling fromJdwpTag:
if (!JDWP_TAG_SET.contains(tag)) {
LOG.warn("Skipping value with non-standard JDWP tag {}", tag);
return null;
}
RuntimeType rt = RuntimeType.fromJdwpTag(tag); Type guard
static boolean isKnownJdwpTag(int tag) {
return switch (tag) {
case JDWP.Tag.ARRAY, JDWP.Tag.BYTE, JDWP.Tag.CHAR, JDWP.Tag.OBJECT,
JDWP.Tag.FLOAT, JDWP.Tag.DOUBLE, JDWP.Tag.INT, JDWP.Tag.LONG,
JDWP.Tag.SHORT, JDWP.Tag.VOID, JDWP.Tag.BOOLEAN, JDWP.Tag.STRING,
JDWP.Tag.THREAD, JDWP.Tag.THREAD_GROUP, JDWP.Tag.CLASS_LOADER,
JDWP.Tag.CLASS_OBJECT -> true;
default -> false;
};
} Try / catch
RuntimeType rt;
try {
rt = RuntimeType.fromJdwpTag(tag);
} catch (SmaliDebuggerException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unexpected value")) {
LOG.warn("Non-standard JDWP tag {}, skipping value", tag);
return null;
}
throw e;
} Prevention
- Debug on stock Android images that emit spec-compliant JDWP tags.
- Keep jadx and its jdwp library current for broader tag coverage.
- Verify ID sizes negotiated in initJDWP so packet decoding stays aligned.
- Make fromJdwpTag return null for unknown tags rather than aborting the session.
When it happens
Trigger: Decoding a JDWP value whose type tag byte is outside the spec's defined set, e.g. a vendor-specific tag from a non-conformant ART build, or a tag read from a misaligned packet buffer so the decoder reads the wrong byte as a tag. Fires while interpreting variable values returned to the debugger.
Common situations: Debugging on an unusual device/ROM whose ART emits tag values not in the standard set; a JDWP packet decode that got out of sync (wrong ID sizes from initJDWP); emulator with a non-standard runtime; reading a value whose encoding the current jdwp library does not model.
Related errors
- Unknown option: {}
- Threads count must be positive, got: {}
- Found {} classes, single class output can't be used
- Class decompilation failed
- Failed to load config file: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/9a5f9e6d3e36e59d.
Report an issue: GitHub.