pardeike/Harmony · error · ArgumentException

[ ]

Error message

{note} [{info.argumentTypes.Description()}]

What it means

In bulk-patch mode, a patch method must not specify argumentTypes to disambiguate overloads, because the target is already fully determined by TargetMethod/TargetMethods/[HarmonyPatchAll]. Harmony rejects the combination to prevent conflicting target selection.

Solutions

  1. Remove argumentTypes from the patch method's attribute and rely on TargetMethods() to yield the exact overload
  2. Move that overload-specific patch into its own patch class without bulk-targeting attributes

Example fix

// before
[HarmonyPatch(typeof(Foo), "Bar", new[] { typeof(int) })]
static void Postfix() { }
// after
static IEnumerable<MethodBase> TargetMethods()
{
    yield return AccessTools.Method(typeof(Foo), "Bar", new[] { typeof(int) });
}
Defensive patterns

Strategy: validation

Validate before calling

if (hasBulkTargeting && patchMethods.Any(p => p.info.argumentTypes != null)) throw ...;

Prevention

When it happens

Trigger: BulkPatch processing a patch method whose HarmonyMethod info.argumentTypes is non-null while TargetMethod/TargetMethods/[HarmonyPatchAll] is in use on the class.

Common situations: Copy-pasting individually annotated overloads into an [HarmonyPatchAll] class; adding [HarmonyPatch(typeof(Foo), "Bar", typeof(int))] attributes next to a TargetMethods() implementation.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at Harmony/Public/PatchClassProcessor.cs:152

		}

		List<MethodInfo> BulkPatch(List<MethodBase> originals, ref MethodBase lastOriginal, bool unpatch)
		{
			var jobs = new PatchJobs<MethodInfo>();
			for (var i = 0; i < originals.Count; i++)
			{
				lastOriginal = originals[i];
				var job = jobs.GetJob(lastOriginal);
				foreach (var patchMethod in patchMethods)
				{
					var note = "You cannot combine TargetMethod, TargetMethods or [HarmonyPatchAll] with individual annotations";
					var info = patchMethod.info;
					if (info.methodName is not null)
						throw new ArgumentException($"{note} [{info.methodName}]");
					if (info.methodType.HasValue && info.methodType.Value != MethodType.Normal)
						throw new ArgumentException($"{note} [{info.methodType}]");
					if (info.argumentTypes is not null)
						throw new ArgumentException($"{note} [{info.argumentTypes.Description()}]");

					job.AddPatch(patchMethod);
				}
			}
			foreach (var job in jobs.GetJobs())
			{
				lastOriginal = job.original;
				if (unpatch)
					ProcessUnpatchJob(job);
				else
					ProcessPatchJob(job);
			}
			return jobs.GetReplacements();
		}

		List<MethodInfo> PatchWithAttributes(ref MethodBase lastOriginal, bool unpatch)
		{
			var jobs = new PatchJobs<MethodInfo>();

View on GitHub (pinned to e7872dc170)