Tencent/matrix · error · IllegalArgumentException
Illegal clazz type
Error message
Illegal clazz type: ${clazz.getClass()} What it means
ReflectUtil.getDeclaredFieldRecursive accepts the declaring class either as a String (class name, loaded via Class.forName) or as a Class object; anything else is rejected with IllegalArgumentException 'Illegal clazz type: X'. The method then walks the superclass chain to find the declared field.
Solutions
- Pass a Class literal (MyClass.class) or the fully-qualified class name string.
- If you have an instance, pass obj.getClass() instead of obj.
- Add a null/instanceof check at the call site before invoking reflection.
- If the class may not be on the classpath, ensure the String form resolves (Class.forName failure would surface separately).
Example fix
// before Field f = ReflectUtil.getDeclaredFieldRecursive(someInstance, "mField"); // after Field f = ReflectUtil.getDeclaredFieldRecursive(someInstance.getClass(), "mField");
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(clazz instanceof String) && !(clazz instanceof Class)) throw new IllegalArgumentException("clazz must be Class or String"); Type guard
static boolean isValidClassRef(Object clazz) {
return clazz instanceof String || clazz instanceof Class<?>;
} Try / catch
try {
Field f = ReflectUtil.getDeclaredFieldRecursive(clazz, fieldName);
} catch (IllegalArgumentException e) {
Log.w(TAG, "bad clazz arg: " + e.getMessage());
} Prevention
- Pass MyClass.class or "com.example.MyClass", never an instance.
- Use obj.getClass() when starting from an instance.
- Keep a single reflection wrapper API and validate args there.
- Watch for refactors that swap a Class parameter for an instance.
When it happens
Trigger: Calling getDeclaredFieldRecursive with an object that is neither String nor Class — e.g. passing an instance instead of its getClass(), a Method/Field object, or a null that trips the else branch.
Common situations: Refactoring call sites where an instance variable replaced a class literal; generic APIs forwarding Object blindly; tests passing mock instances.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Both of invoker and fieldName can not be null or nil.
- obj is not closeable
- unable to cast object
- Method is not exists.
- Both of invoker and fieldName can not be null or nil.
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/7e21981ef570af81.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-commons/src/main/java/com/tencent/matrix/javalib/util/ReflectUtil.java:35
package com.tencent.matrix.javalib.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by caichongyang on 17/7/4.
*/
public final class ReflectUtil {
public static Field getDeclaredFieldRecursive(Object clazz, String fieldName) throws NoSuchFieldException, ClassNotFoundException {
Class<?> realClazz = null;
if (clazz instanceof String) {
realClazz = Class.forName((String) clazz);
} else if (clazz instanceof Class) {
realClazz = (Class<?>) clazz;
} else {
throw new IllegalArgumentException("Illegal clazz type: " + clazz.getClass());
}
Class<?> currClazz = realClazz;
while (true) {
try {
Field field = currClazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
if (currClazz.equals(Object.class)) {
throw e;
}
currClazz = currClazz.getSuperclass();
}
}
}
public static Method getDeclaredMethodRecursive(Object clazz, String methodName, Class<?>... argTypes) throws NoSuchMethodException, ClassNotFoundException {
Class<?> realClazz = null;View on GitHub (pinned to 3b8293bd65)