pardeike/Harmony · error · ArgumentNullException

Value cannot be null. (Parameter 'method')

Error message

Value cannot be null. (Parameter 'method')

What it means

Harmony's MethodCopier.GetInstructions guards that both the ILGenerator and the MethodBase being copied are non-null before reading the method body. A null 'method' means Harmony was asked to disassemble/instrument a method reference that resolved to null (or was never passed in), typically by a caller of GetInstructions or the public PatchInfo/Transpiler APIs that feed it. The library fails fast here instead of throwing a confusing NullReferenceException deeper in the IL reader.

Solutions

  1. Fix the reflection lookup so the MethodBase is actually found (correct name, BindingFlags including Static/Instance/NonPublic/Public)
  2. Check for null before calling any Harmony API and fail with a clear message naming the target you intended to patch
  3. If the target may be absent in some game versions, guard the patch application behind a version check and skip gracefully
  4. Verify you are not passing the output of GetPatchInfo or another optional result where a MethodBase is required

Example fix

// before
var m = typeof(Game).GetMethod("Update");
harmony.Patch(m, prefix: new HarmonyMethod(typeof(P), nameof(P.Pre)));
// after
var m = typeof(Game).GetMethod("Update", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)
    ?? throw new MissingMethodException(typeof(Game).FullName, "Update");
harmony.Patch(m, prefix: new HarmonyMethod(typeof(P), nameof(P.Pre)));
Defensive patterns

Strategy: validation

Validate before calling

var target = AccessTools.Method(typeof(Game), "Update") ?? throw new MissingMethodException(typeof(Game).FullName, "Update");
// then pass 'target' to harmony.Patch / PatchProcessor

Type guard

static MethodInfo RequireMethod(Type t, string name) =>
    t.GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
    ?? throw new InvalidOperationException($"{t.FullName}.{name} not found");

Prevention

When it happens

Trigger: Calling Harmony.GetPatchInfo, PatchProcessor, or GetOriginalInstructions-style APIs with a null MethodInfo; a reflection lookup (Type.GetMethod) returned null and the result was passed on without checking; a patch target was removed/renamed so a stored reference is now null.

Common situations: Mods (RimWorld, BepInEx, MelonLoader) patching targets found by string name where a game update renamed the method; passing typeof(X).GetMethod("name") straight into PatchClassProcessor/PatchProcessor without null checks; wrong BindingFlags so the lookup misses the method.

Related errors


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

Appendix: source

Thrown at Harmony/Internal/MethodCopier.cs:46

			if (config.MethodBase is null)
				throw new ArgumentNullException("config.methodbase");
			reader = new MethodBodyReader(config.MethodBase, config.il);
			reader.DeclareVariables(config.originalVariables);
			reader.GenerateInstructions();
			reader.SetDebugging(config.debug);
		}

		internal void AddTranspiler(MethodInfo transpiler) => transpilers.Add(transpiler);

		internal List<CodeInstruction> Finalize(bool stripLastReturn, out bool hasReturnCode, out bool methodEndsInDeadCode, List<Label> endLabels)
			=> reader.FinalizeILCodes(transpilers, stripLastReturn, out hasReturnCode, out methodEndsInDeadCode, endLabels);

		internal static List<CodeInstruction> GetInstructions(ILGenerator generator, MethodBase method, int maxTranspilers)
		{
			if (generator is null)
				throw new ArgumentNullException(nameof(generator));
			if (method is null)
				throw new ArgumentNullException(nameof(method));

			var originalVariables = MethodPatcherTools.DeclareOriginalLocalVariables(generator, method);
			var copier = new MethodCopier(method, generator, originalVariables);

			var info = Harmony.GetPatchInfo(method);
			if (info is not null)
			{
				var sortedTranspilers = PatchFunctions.GetSortedPatchMethods(method, [.. info.Transpilers], false);
				for (var i = 0; i < maxTranspilers && i < sortedTranspilers.Count; i++)
					copier.AddTranspiler(sortedTranspilers[i]);
			}

			return copier.Finalize(false, out _, out _, null);
		}
	}

	internal class MethodBodyReader
	{

View on GitHub (pinned to e7872dc170)