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
- Verify the method exists on the type (AccessTools.Method(type, name) != null) and check spelling/case
- Supply the exact parameters array to disambiguate overloads
- Resolve the MethodInfo yourself first and use new CodeInstruction(OpCodes.Call, mi) so a clear null-check/log precedes the failure
- 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
- Use nameof() and the Type-based overload instead of strings
- Specify parameter types for overloaded methods
- Null-check AccessTools.Method at patch init against all supported target versions
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
- No method found for , parameters= , generics=
- No field found for and
- Cannot not find method for type
- Ambiguous match for HarmonyMethod
- VariableState: variable of type
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)