pardeike/Harmony · error · HarmonyException
Ambiguous match for HarmonyMethod
Error message
Ambiguous match for HarmonyMethod[{attr.Description()}] What it means
Harmony's GetOriginalMethod resolves the original method from a HarmonyMethod attribute, e.g. for patching operators like op_Addition. When AccessTools.DeclaredMethod finds multiple overloads matching the name (and optionally argument types), .NET throws AmbiguousMatchException, which Harmony wraps in this HarmonyException so the attribute description is included.
Solutions
- Set attr.argumentTypes to the exact parameter types of the overload you want to patch
- If patching an operator, verify the operator does not have multiple implementations (e.g. lhs/rhs vs lifted nullable forms); pick argumentTypes accordingly
- Catch HarmonyException and inspect the inner AmbiguousMatchException plus the attribute Description() to see which method name/type was ambiguous
- Patch the specific overload via a HarmonyMethod constructed from a MethodInfo instead of by name
Example fix
// before
[HarmonyPatch(typeof(Vector3), MethodType.Normal, nameof(Vector3.Add))]
// after
[HarmonyPatch(typeof(Vector3), nameof(Vector3.Add), new[] { typeof(Vector3) })] Defensive patterns
Strategy: validation
Validate before calling
var mi = AccessTools.DeclaredMethod(attr.declaringType, "op_" + attr.methodType.ToString().Replace("Operator", ""), attr.argumentTypes);
if (mi is null) throw new InvalidOperationException($"No unique method for {attr.Description()}; specify argumentTypes"); Type guard
bool IsResolvable(HarmonyMethod attr) => AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes) is not null;
Try / catch
try { PatchOriginalMethod(attr); } catch (HarmonyException ex) when (ex.InnerException is AmbiguousMatchException) { log.Error($"Ambiguous patch target: {ex.Message}", ex); } Prevention
- Always specify argumentTypes when patching overloaded methods or operators
- Prefer patching via MethodInfo over name-based resolution
- Re-run patches in CI against every supported target-assembly version
When it happens
Trigger: Patching a type that declares an overloaded method via attr.methodType (e.g. methodType derived from a name like 'Add') or an operator/overload where attr.argumentTypes is null or not specific enough, so more than one declared method matches the resolved name.
Common situations: Patching operator overloads (e.g. op_Addition with multiple implicit-conversion-compatible operand combinations), patching overloaded methods by name without specifying argumentTypes, and switching .NET versions where an extra overload was added to a base class library type.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot not find method for type
- argumentVariations contains more elements than argumentTypes
- No method found for type=
- No method found for , parameters= , generics=
- No field found for and
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/6bb138c799a0bcf4.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Internal/PatchTools.cs:203
case MethodType.OperatorBitwiseAnd:
case MethodType.OperatorBitwiseOr:
case MethodType.OperatorExclusiveOr:
case MethodType.OperatorLeftShift:
case MethodType.OperatorRightShift:
case MethodType.OperatorEquality:
case MethodType.OperatorInequality:
case MethodType.OperatorGreaterThan:
case MethodType.OperatorLessThan:
case MethodType.OperatorGreaterThanOrEqual:
case MethodType.OperatorLessThanOrEqual:
case MethodType.OperatorComma:
var methodName = "op_" + attr.methodType.ToString().Replace("Operator", "");
return AccessTools.DeclaredMethod(attr.declaringType, methodName, attr.argumentTypes);
}
}
catch (AmbiguousMatchException ex)
{
throw new HarmonyException($"Ambiguous match for HarmonyMethod[{attr.Description()}]", ex.InnerException ?? ex);
}
return null;
}
}
}
View on GitHub (pinned to e7872dc170)