pardeike/Harmony · error · ArgumentNullException

. is NULL

Error message

{nameof(standin)}.{nameof(standin.method)} is NULL

What it means

ReversePatch requires a stand-in HarmonyMethod whose .method property holds the method to reverse-patch. Harmony throws this ArgumentNullException (with a custom message) when HarmonyMethod instance is valid but its method field was never assigned.

Solutions

  1. Pass a valid MethodInfo when constructing the HarmonyMethod: new HarmonyMethod(AccessTools.Method(typeof(Target), nameof(Target.Run))).
  2. Check standin.method before calling and construct the HarmonyMethod from the correct method.
  3. If copying a HarmonyMethod, ensure the method field is carried over (clone with new HarmonyMethod(methodInfo)).

Example fix

// before
var standin = new HarmonyMethod(); // method is null
harmony.CreateReversePatcher(original, standin);

// after
var standin = new HarmonyMethod(AccessTools.Method(typeof(MyPatch), nameof(MyPatch.Snapshot)));
harmony.CreateReversePatcher(original, standin);
Defensive patterns

Strategy: type-guard

Validate before calling

if (standin is null || standin.method is null)
    throw new InvalidOperationException("CreateReversePatcher requires HarmonyMethod with a valid method");

Type guard

static bool IsValidStandin(HarmonyMethod hm) => hm?.method is MethodInfo;

Try / catch

try { var rp = harmony.CreateReversePatcher(original, standin); rp.Patch(); }
catch (ArgumentNullException ex)
{ Logger.Error($"ReversePatch stand-in invalid: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling PatchFunctions.ReversePatch (e.g. harmony.CreateReversePatcher or ReversePatch) with a HarmonyMethod built without a MethodInfo, e.g. new HarmonyMethod() with no method argument, or one deserialized/copied with method lost.

Common situations: Creating a HarmonyMethod from a patch class annotation where the info field wasn't bound, copying HarmonyMethod properties between instances, or calling CreateReversePatcher with a HarmonyMethod(null).

Related errors


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

Appendix: source

Thrown at Harmony/Internal/PatchFunctions.cs:55

			if (replacement is null) throw new MissingMethodException($"Cannot create replacement for {original.FullDescription()}");

			try
			{
				PatchTools.DetourMethod(original, replacement);
			}
			catch (Exception ex)
			{
				throw HarmonyException.Create(ex, finalInstructions);
			}
			return replacement;
		}

		internal static MethodInfo ReversePatch(HarmonyMethod standin, MethodBase original, MethodInfo postTranspiler)
		{
			if (standin is null)
				throw new ArgumentNullException(nameof(standin));
			if (standin.method is null)
				throw new ArgumentNullException(nameof(standin), $"{nameof(standin)}.{nameof(standin.method)} is NULL");

			var debug = (standin.debug ?? false) || Harmony.DEBUG;

			var transpilers = new List<MethodInfo>();
			if (standin.reversePatchType == HarmonyReversePatchType.Snapshot)
			{
				var info = Harmony.GetPatchInfo(original);
				transpilers.AddRange(GetSortedPatchMethods(original, [.. info.Transpilers], debug));
			}
			if (postTranspiler is not null) transpilers.Add(postTranspiler);

			var emptyFix = new List<MethodInfo>();
			var emptyInner = new List<Infix>();
			var patcher = new MethodCreator(new MethodCreatorConfig(
				standin.method,
				original,
				emptyFix,
				emptyFix,

View on GitHub (pinned to e7872dc170)