{"record":{"id":"fd49c9fc201ca914","repo":"pardeike/Harmony","slug":"ambiguous-match-in-harmony-patch-for-type-name","errorCode":null,"errorMessage":"Ambiguous match in Harmony patch for {type}:{name}","messagePattern":"Ambiguous match in Harmony patch for (.+?):(.+?)","errorType":"exception","errorClass":"AmbiguousMatchException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/AccessTools.cs","lineNumber":707,"sourceCode":"\t\t\tif (string.IsNullOrEmpty(name))\r\n\t\t\t{\r\n\t\t\t\tFileLog.Debug(\"AccessTools.Method: name is null/empty\");\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\t\t\tMethodInfo result;\r\n\t\t\tvar modifiers = new ParameterModifier[] { };\r\n\t\t\tif (parameters is null)\r\n\t\t\t{\r\n\t\t\t\ttry\r\n\t\t\t\t{\r\n\t\t\t\t\tresult = FindIncludingBaseTypes(type, t => t.GetMethod(name, all));\r\n\t\t\t\t}\r\n\t\t\t\tcatch (AmbiguousMatchException ex)\r\n\t\t\t\t{\r\n\t\t\t\t\tresult = FindIncludingBaseTypes(type, t => t.GetMethod(name, all, null, [], modifiers));\r\n\t\t\t\t\tif (result is null)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tthrow new AmbiguousMatchException($\"Ambiguous match in Harmony patch for {type}:{name}\", ex);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tresult = FindIncludingBaseTypes(type, t => t.GetMethod(name, all, null, parameters, modifiers));\r\n\t\t\t}\r\n\r\n\t\t\tif (result is null)\r\n\t\t\t{\r\n\t\t\t\tFileLog.Debug($\"AccessTools.Method: Could not find method for type {type} and name {name} and parameters {parameters?.Description()}\");\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\tif (generics is not null)\r\n\t\t\t\tresult = result.MakeGenericMethod(generics);\r\n\t\t\treturn result;\r\n\t\t}\r","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/AccessTools.cs#L689-L725","documentation":"AccessTools.Method rethrows AmbiguousMatchException when Type.GetMethod finds several methods with the same name. Harmony first tries a fallback lookup via FindIncludingBaseTypes; if that also cannot resolve a unique match, it throws this message with the original exception as InnerException. It signals that the name alone is not enough to identify the patch target.","triggerScenarios":"AccessTools.Method(typeof(T), \"MethodName\") where the type (including base types) has multiple methods named MethodName and no `parameters` argument was given to disambiguate; also hit by patch helpers like EnumeratorMoveNext, Finalizer lookups, and m_PrepForRemoting resolution that go through AccessTools.Method.","commonSituations":"Patching overloaded methods such as `Process(string)` vs `Process(object)`, interface + class implementations, or a method overloaded in a base and derived type; very common in Unity/game modding where framework types have many overloads.","solutions":["Pass parameter types: AccessTools.Method(typeof(T), \"Process\", new[] { typeof(string) })","Or pass an expression: AccessTools.Method((Action<T, string>)instance.Process) to pin the exact overload","List candidates with AccessTools.GetDeclaredMethods(typeof(T)).Where(m => m.Name == \"Process\") and pick by signature"],"exampleFix":"// before\nvar m = AccessTools.Method(typeof(Foo), \"Process\");\n// after\nvar m = AccessTools.Method(typeof(Foo), \"Process\", new[] { typeof(string), typeof(int) });","handlingStrategy":"validation","validationCode":"var candidates = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(m => m.Name == name).ToList();\nif (candidates.Count > 1 && parameters is null) throw new InvalidOperationException(\"Overloads found: pass parameters\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always disambiguate with a parameters array when a method has overloads","Use expression-based overloads (AccessTools.Method(() => instance.M())) for compile-time safety","Pin target assembly versions; overloads appear across game/framework updates"],"tags":["reflection","harmony","ambiguity","overload"],"backgroundTag":"invalid-argument-value","analyzedSha":"e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c","analyzedAt":"2026-09-15T22:47:11.550Z","contentChangedAt":"2026-09-15T22:47:11.550Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}