skylot/jadx · error · JadxRuntimeException
Null class type
Error message
Null class type
What it means
Thrown by ClassInfo.checkClassType when the ArgType passed to build a ClassInfo is null. Every ClassInfo must be backed by a non-null class type; a null type is an unrecoverable programming error rather than bad input data.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java:52
if (cls != null) {
return cls;
}
boolean canBeInner = root.getArgs().isMoveInnerClasses();
ClassInfo newClsInfo = new ClassInfo(root, clsType, canBeInner);
return root.getInfoStorage().putCls(newClsInfo);
}
public static ClassInfo fromName(RootNode root, String clsName) {
return fromType(root, ArgType.object(clsName));
}
public static ClassInfo fromNameWithoutCache(RootNode root, String fullClsName, boolean canBeInner) {
return new ClassInfo(root, ArgType.object(fullClsName), canBeInner);
}
private static ArgType checkClassType(ArgType type) {
if (type == null) {
throw new JadxRuntimeException("Null class type");
}
if (type.isArray()) {
// TODO: check case with method declared in array class like ( clone in int[])
return ArgType.OBJECT;
}
if (!type.isObject() || type.isGenericType()) {
throw new JadxRuntimeException("Not class type: " + type);
}
if (type.isGeneric()) {
return ArgType.object(type.getObject());
}
return type;
}
public void changeShortName(String aliasName) {
ClassAliasInfo newAlias;
String aliasPkg = getAliasPkg();
if (Objects.equals(name, aliasName) || StringUtils.isEmpty(aliasName)) {View on GitHub (pinned to e738a26571)
Solutions
- Ensure a non-null ArgType is always supplied; guard the caller with Objects.requireNonNull(type, "class type").
- If the class name may be unknown, check it before calling fromName and handle the missing-class case explicitly.
- Trace which caller passed null - it usually indicates a prior parsing/resolution failure that should have been handled earlier.
- Add a unit test asserting fromName rejects null with a clear message.
Example fix
// before
ArgType type = resolveType(maybeNull);
ClassInfo info = ClassInfo.fromType(root, type); // throws if type null
// after
ArgType type = resolveType(maybeNull);
if (type == null) {
throw new IllegalArgumentException("Class type could not be resolved for: " + maybeNull);
}
ClassInfo info = ClassInfo.fromType(root, type); Defensive patterns
Strategy: validation
Validate before calling
if (type == null) {
throw new IllegalArgumentException("Cannot build ClassInfo from null type");
} Type guard
static boolean isNonNullOrThrow(ArgType t, String ctx) {
if (t == null) throw new IllegalArgumentException("Null type in " + ctx);
return true;
} Try / catch
ClassInfo info;
try {
info = ClassInfo.fromType(root, type);
} catch (JadxRuntimeException e) {
throw new IllegalArgumentException("Class type was null; resolve the name first", e);
} Prevention
- Resolve class names to non-null types before building ClassInfo.
- Guard with Objects.requireNonNull at the call boundary.
- Investigate why a prior resolution step produced null - fix it upstream.
When it happens
Trigger: Calling ClassInfo.fromType / fromName / the constructor with a null ArgType, or a code path where ArgType.object(null) produced a null. Reachable from any class-resolution path that fails to supply a type.
Common situations: Library/plugin code that resolves a class by a name that yielded null; a malformed type string parsed to null; NPE-masked flows where the type field was never set.
Related errors
- Not class type: {}
- Can't change package for inner class: {}
- Can't change package for inner class
- Package is null for not inner class
- Unknown type in literalToString:
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/6565eb6d148b377f.
Report an issue: GitHub.