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

  1. Ensure a non-null ArgType is always supplied; guard the caller with Objects.requireNonNull(type, "class type").
  2. If the class name may be unknown, check it before calling fromName and handle the missing-class case explicitly.
  3. Trace which caller passed null - it usually indicates a prior parsing/resolution failure that should have been handled earlier.
  4. 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

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


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/6565eb6d148b377f. Report an issue: GitHub.