pardeike/Harmony · error · Exception
Cannot find method for expression
Error message
Cannot find method for expression {expression} What it means
GetMethodInfo succeeded in finding a MethodCallExpression in the lambda, but its .Method property was null. This happens in rare cases (e.g. reduced dynamic call nodes) where the call node exists but no concrete MethodInfo can be resolved. Harmony throws a plain Exception with the offending expression in the message.
Solutions
- Verify the lambda uses a normal, compile-time-resolvable method call rather than a manually constructed expression tree
- If building expressions by hand, ensure Expression.Call receives a non-null MethodInfo before passing the lambda to GetMethodInfo
- Bypass the helper: capture the MethodInfo directly (typeof(T).GetMethod("Name", flags)) instead of via expression
Example fix
// before
var expr = Expression.Lambda<Func<int>>(Expression.Call(default(MethodInfo)));
var m = SymbolExtensions.GetMethodInfo(expr);
// after
var m = typeof(SomeType).GetMethod("Target", BindingFlags.Public | BindingFlags.Static); Defensive patterns
Strategy: try-catch
Validate before calling
if (expr.Body is MethodCallExpression { Method: null })
throw new InvalidOperationException("Expression tree has a call node without a MethodInfo"); Type guard
static MethodInfo SafeMethod(LambdaExpression e) =>
(e.Body as MethodCallExpression)?.Method ??
(e.Body as UnaryExpression)?.Operand is MethodCallExpression m ? m.Method : null; Try / catch
MethodInfo mi;
try { mi = SymbolExtensions.GetMethodInfo(expr); }
catch (Exception) { mi = typeof(T).GetMethod("Name", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); } Prevention
- Avoid hand-built or reduced expression trees with GetMethodInfo; use plain compile-time lambdas
- Ensure Expression.Call always receives a non-null MethodInfo when constructing trees manually
- Keep a name-based reflection fallback ready for exotic expression shapes
When it happens
Trigger: Passing an Expression<Func<T>> whose body is a MethodCallExpression with a null Method property — practically only seen with unusual/dynamic call expressions or compiler-generated reduced nodes, not ordinary lambdas.
Common situations: Extremely rare in normal use; typically encountered when building expression trees manually (Expression.Call with a null method) or with exotic dynamic proxies feeding GetMethodInfo.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- The type must declare an empty constructor (the constructor…
- Value cannot be null. (Parameter 'fromMethod')
- Value cannot be null. (Parameter 'method')
- Value cannot be null. (Parameter 'config.original')
- Ambiguous match for HarmonyMethod
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/b6a35a5cfce88b67.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Tools/SymbolExtensions.cs:49
/// <summary>Given a lambda expression that calls a method, returns the method info</summary>
/// <param name="expression">The lambda expression using the method</param>
/// <returns>The method in the lambda expression</returns>
///
public static MethodInfo GetMethodInfo(LambdaExpression expression)
{
var outermostExpression = expression.Body as MethodCallExpression;
if (outermostExpression is null)
{
if (expression.Body is UnaryExpression ue && ue.Operand is MethodCallExpression me && me.Object is System.Linq.Expressions.ConstantExpression ce && ce.Value is MethodInfo mi)
return mi;
throw new ArgumentException("Invalid Expression. Expression should consist of a Method call only.");
}
var method = outermostExpression.Method;
if (method is null)
throw new Exception($"Cannot find method for expression {expression}");
return method;
}
/// <summary>Given a lambda expression that accesses a field, returns the field info</summary>
/// <typeparam name="T">The generic field type</typeparam>
/// <param name="expression">The lambda expression using the field</param>
/// <returns>The field in the lambda expression</returns>
///
public static FieldInfo GetFieldInfo<T>(Expression<Func<T>> expression) => GetFieldInfo((LambdaExpression)expression);
/// <summary>Given a lambda expression that accesses a field, returns the field info</summary>
/// <param name="expression">The lambda expression using the field</param>
/// <returns>The field in the lambda expression</returns>
///
public static FieldInfo GetFieldInfo(LambdaExpression expression)
{
if (expression is null)
View on GitHub (pinned to e7872dc170)