skylot/jadx · error · JadxRuntimeException
Bad name for type variable: {}
Error message
Bad name for type variable: {} What it means
Thrown by SignatureParser when parsing a JVM generics type-variable reference (the 'T...;' form in a signature string) and the extracted variable name contains a ')' character. A well-formed type variable name is an identifier like 'T' or 'K'; a closing parenthesis indicates the parser has run past the end of the type-variable token into an enclosing method signature, i.e. the signature is malformed or was produced by an aggressive obfuscator. This is a defensive integrity check — jadx refuses to build a generic type from a name that is syntactically impossible in valid bytecode.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/nodes/parser/SignatureParser.java:149
}
public ArgType consumeType() {
char ch = next();
switch (ch) {
case 'L':
ArgType obj = consumeObjectType(false);
if (obj != null) {
return obj;
}
break;
case 'T':
next();
mark();
String typeVarName = consumeUntil(';');
if (typeVarName != null) {
consume(';');
if (typeVarName.contains(")")) {
throw new JadxRuntimeException("Bad name for type variable: " + typeVarName);
}
return ArgType.genericType(typeVarName);
}
break;
case '[':
return ArgType.array(consumeType());
case STOP_CHAR:
return null;
default:
// primitive type (one char)
ArgType type = ArgType.parse(ch);
if (type != null) {
return type;
}
break;View on GitHub (pinned to e738a26571)
Solutions
- Upgrade to the latest jadx release — signature-parser robustness improvements land frequently and may make this a recoverable warning instead of a crash.
- If using jadx as a library, catch JadxRuntimeException around the per-class decompilation call and skip the offending class so the batch continues.
- Reproduce with the minimal APK/DEX and file a jadx issue including the full signature string from the error message so the parser can be hardened.
- As a stopgap, strip the Signature attribute from the offending class with a bytecode editor (e.g. ASM) before decompiling, trading generics info for a successful decompile.
Example fix
// before — unguarded decompile call
for (JavaClass cls : jadx.getClasses()) {
String code = cls.getCode();
}
// after — skip class on parser failure
for (JavaClass cls : jadx.getClasses()) {
try {
String code = cls.getCode();
} catch (JadxRuntimeException e) {
LOG.warn("Skipping {}: {}", cls.getName(), e.getMessage());
}
} Defensive patterns
Strategy: try-catch
Try / catch
// Wrap per-class decompilation; malformed signatures are not preventable
for (JavaClass cls : jadx.getClasses()) {
try {
String code = cls.getCode();
results.put(cls.getName(), code);
} catch (JadxRuntimeException e) {
LOG.warn("Signature parse error in {}: {}", cls.getName(), e.getMessage());
}
} Prevention
- Use the latest jadx version — signature-parser robustness improves each release.
- Process classes individually with try-catch rather than calling jadx.save() on the whole batch unguarded.
- Validate input DEX/JAR files with dexdump or baksmali before decompiling to catch gross corruption early.
- Keep the original APK so you can file reproducible bug reports with the failing class.
When it happens
Trigger: consumeType() hits case 'T', calls consumeUntil(';'), gets a non-null string, then typeVarName.contains(")") is true. This happens when a class or method Signature attribute contains something like 'TT);' — a type variable token that leaks a paren, which violates the JVMS signature grammar.
Common situations: Decompiling APKs obfuscated by tools that corrupt or hand-craft Signature attributes (e.g. some variants of Allatori, custom obfuscators). Also seen with DEX files produced by non-standard compilers or bytecode rewriters that emit invalid generic signatures. Rare with stock javac/d8/r8 output.
Related errors
- Can't parse type: {}, unexpected: {}
- No inner type found: {}
- Unexpected inner type found: {}
- Failed to parse generic types map
- Unexpected end of signature
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/9ec40f773d88c535.
Report an issue: GitHub.