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

  1. Verify the lambda uses a normal, compile-time-resolvable method call rather than a manually constructed expression tree
  2. If building expressions by hand, ensure Expression.Call receives a non-null MethodInfo before passing the lambda to GetMethodInfo
  3. 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

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


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)