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
- Ensure the Class argument is non-null before constructing (check the result of Class.forName or the constant class reference).
- Ensure the method-name string is non-null and non-empty; trim and validate any dynamically built name.
- 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.
- 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
- Validate class and method-name arguments before constructing ReflectMethod.
- Never build method names by unchecked string concatenation; log the built name.
- Use Kotlin non-null types to push the check to compile time.
- Keep a null-check helper (e.g. Util.isNullOrNil) in your reflective utilities.
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
- must not be null
- Matrix init, Matrix should not be null.
- matrix init, application is null
- plugin start, plugin listener is null
- 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/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)