Tencent/matrix · error · IllegalArgumentException

Both of invoker and fieldName can not be null or nil.

Error message

Both of invoker and fieldName can not be null or nil.

What it means

ReflectMethod is a reflective helper that lazily resolves a java.lang.Method by name and parameter types from a target class. The constructor validates that both the target class and the method name are provided; if either is null or the method name is an empty string, it throws this IllegalArgumentException immediately (the message's 'invoker'/'fieldName' wording is a copy-paste artifact from a sibling class, but it means clazz/methodName). Failing fast here prevents a useless ReflectMethod instance that could never be invoked.

Solutions

  1. Ensure the Class argument is non-null before constructing (check the result of Class.forName or the constant class reference).
  2. Ensure the method-name string is non-null and non-empty; trim and validate any dynamically built name.
  3. If the method may legitimately be absent, verify the name against the target class with clazz.getDeclaredMethod(...) in a try/catch instead of passing a blank name.
  4. For Kotlin callers, declare parameters as non-null types (Class, String) so the compiler rejects nulls at compile time.

Example fix

// before
ReflectMethod method = new ReflectMethod(getCachedClass(name), buildMethodName(prefix), paramTypes);
// after
Class<?> clazz = getCachedClass(name);
String methodName = buildMethodName(prefix);
if (clazz == null || methodName == null || methodName.isEmpty()) {
    MatrixLog.w(TAG, "skip reflection: clazz=%s methodName=%s", name, methodName);
    return;
}
ReflectMethod method = new ReflectMethod(clazz, methodName, paramTypes);
Defensive patterns

Strategy: validation

Validate before calling

if (clazz == null) throw new IllegalArgumentException("clazz must not be null");
if (methodName == null || methodName.isEmpty()) throw new IllegalArgumentException("methodName must not be empty");
ReflectMethod m = new ReflectMethod(clazz, methodName, paramTypes);

Type guard

boolean isValidTarget(Class<?> clazz, String name) {
    return clazz != null && name != null && !name.isEmpty();
}

Try / catch

try {
    ReflectMethod m = new ReflectMethod(clazz, methodName);
} catch (IllegalArgumentException e) {
    MatrixLog.w(TAG, "invalid reflection target: %s", e.getMessage());
}

Prevention

When it happens

Trigger: new ReflectMethod(null, "someMethod") — clazz is null; or new ReflectMethod(SomeClass.class, null) / new ReflectMethod(SomeClass.class, "") — methodName is null or empty. Any parameterTypes are irrelevant to this check.

Common situations: Passing a Class fetched reflectively (Class.forName on a miss returns via exception but callers sometimes cache a null), building method names dynamically from string concatenation that yields "" or null (e.g. a config-driven hook name), or calling from Kotlin where a null String slipped through platform types.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/4d4fb3ef7ca85c2a. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/util/ReflectMethod.java:18

package com.tencent.matrix.util;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectMethod {
    private static final String TAG = "ReflectFiled";
    private Class<?> mClazz;
    private String mMethodName;

    private boolean mInit;
    private Method mMethod;
    private Class[] mParameterTypes;

    public ReflectMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
        if (clazz == null || methodName == null || methodName.length() == 0) {
            throw new IllegalArgumentException("Both of invoker and fieldName can not be null or nil.");
        }
        this.mClazz = clazz;
        this.mMethodName = methodName;
        this.mParameterTypes = parameterTypes;
    }

    private synchronized void prepare() {
        if (mInit) {
            return;
        }
        Class<?> clazz = mClazz;
        while (clazz != null) {
            try {
                Method method = clazz.getDeclaredMethod(mMethodName, mParameterTypes);
                method.setAccessible(true);
                mMethod = method;
                break;
            } catch (Exception e) {

View on GitHub (pinned to 3b8293bd65)