pardeike/Harmony · error · ArgumentException

No method found for type=

Error message

No method found for type={type}, name={name}, parameters={parameters.Description()}, generics={generics.Description()}

What it means

CodeInstruction.Call(Type, string, ...) resolves the method via AccessTools.Method and emits a CALL instruction. If no method on the given type matches the name (and optional parameter/generic constraints), Harmony throws ArgumentException rather than emitting an invalid call.

Solutions

  1. Verify the method exists on the type (AccessTools.Method(type, name) != null) and check spelling/case
  2. Supply the exact parameters array to disambiguate overloads
  3. Resolve the MethodInfo yourself first and use new CodeInstruction(OpCodes.Call, mi) so a clear null-check/log precedes the failure
  4. Guard against target-version changes with an AccessTools.Method null check at patch startup

Example fix

// before
var call = CodeInstruction.Call(typeof(Logger), "WriteMsg");
// after
var call = CodeInstruction.Call(typeof(Logger), nameof(Logger.WriteMessage), new[] { typeof(string) });
Defensive patterns

Strategy: validation

Validate before calling

var mi = AccessTools.Method(type, name, parameters, generics);
if (mi is null) throw new InvalidOperationException($"Cannot emit call: {type}.{name} not found");

Type guard

bool MethodExists(Type t, string n) => AccessTools.Method(t, n) is not null;

Try / catch

try { il.Append(CodeInstruction.Call(type, name, parameters)); } catch (ArgumentException ex) { log.Error($"CodeInstruction.Call failed for {type?.Name}.{name}", ex); throw; }

Prevention

When it happens

Trigger: Calling CodeInstruction.Call(typeof(T), "MethodName") where MethodName does not exist, was renamed, is inherited-but-not-found by the resolver, or where the parameters/generics arrays filter out all overloads.

Common situations: Target library updated and renamed/removed the method; typo in method name; using method name only when a property getter (get_X) or overload set needs parameters specified; case-sensitivity mismatches.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15). Data as JSON: /api/errors/7943e1f1f5c427c2. Report an issue: GitHub.

Appendix: source

Thrown at Harmony/Public/CodeInstruction.cs:115

		{
			var instruction = Clone();
			instruction.operand = operand;
			return instruction;
		}

		// --- CALLING

		/// <summary>Creates a CodeInstruction calling a method (CALL)</summary>
		/// <param name="type">The class/type where the method is declared</param>
		/// <param name="name">The name of the method (case sensitive)</param>
		/// <param name="parameters">Optional parameters to target a specific overload of the method</param>
		/// <param name="generics">Optional list of types that define the generic version of the method</param>
		/// <returns>A code instruction that calls the method matching the arguments</returns>
		///
		public static CodeInstruction Call(Type type, string name, Type[] parameters = null, Type[] generics = null)
		{
			var method = AccessTools.Method(type, name, parameters, generics);
			if (method is null) throw new ArgumentException($"No method found for type={type}, name={name}, parameters={parameters.Description()}, generics={generics.Description()}");
			return new CodeInstruction(OpCodes.Call, method);
		}

		/// <summary>Creates a CodeInstruction calling a method (CALL)</summary>
		/// <param name="typeColonMethodname">The target method in the form <c>TypeFullName:MethodName</c>, where the type name matches a form recognized by <a href="https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype">Type.GetType</a> like <c>Some.Namespace.Type</c>.</param>
		/// <param name="parameters">Optional parameters to target a specific overload of the method</param>
		/// <param name="generics">Optional list of types that define the generic version of the method</param>
		/// <returns>A code instruction that calls the method matching the arguments</returns>
		///
		public static CodeInstruction Call(string typeColonMethodname, Type[] parameters = null, Type[] generics = null)
		{
			var method = AccessTools.Method(typeColonMethodname, parameters, generics);
			if (method is null) throw new ArgumentException($"No method found for {typeColonMethodname}, parameters={parameters.Description()}, generics={generics.Description()}");
			return new CodeInstruction(OpCodes.Call, method);
		}

		/// <summary>Creates a CodeInstruction calling a method (CALL)</summary>
		/// <param name="expression">The lambda expression using the method</param>

View on GitHub (pinned to e7872dc170)