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

  1. Pass a Class literal (MyClass.class) or the fully-qualified class name string.
  2. If you have an instance, pass obj.getClass() instead of obj.
  3. Add a null/instanceof check at the call site before invoking reflection.
  4. 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

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


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)