pardeike/Harmony · error · NullReferenceException

Patch method cannot be null

Error message

Patch method cannot be null

What it means

AttributePatch.Create converts a MethodInfo annotated with Harmony attributes into an AttributePatch. It throws NullReferenceException immediately if the supplied patch MethodInfo itself is null, since nothing can be reflected on.

Solutions

  1. Verify the MethodInfo lookup before creating the patch: assert AccessTools.Method returned non-null.
  2. Use AccessTools.Method(typeof(PatchClass), nameof(PatchClass.Prefix)) so renaming breaks at compile time.
  3. Null-check lookups and log a clear message instead of passing null into Harmony APIs.

Example fix

// before
AttributePatch.Create(AccessTools.Method(typeof(P), "Preffix")); // null: typo

// after
var patch = AccessTools.Method(typeof(P), nameof(P.Prefix));
if (patch is null) throw new InvalidOperationException("Patch method missing");
AttributePatch.Create(patch);
Defensive patterns

Strategy: validation

Validate before calling

var patch = AccessTools.Method(typeof(MyPatches), nameof(MyPatches.Prefix));
if (patch is null)
    throw new InvalidOperationException("Patch method not found — check name/signature");

Type guard

static MethodInfo RequireMethod(Type t, string name) =>
    AccessTools.Method(t, name) ?? throw new InvalidOperationException($"{t.Name}.{name} not found");

Try / catch

try { AttributePatch.Create(patch); }
catch (NullReferenceException ex) when (ex.Message.Contains("Patch method cannot be null"))
{ Logger.Error("Patch MethodInfo was null"); }

Prevention

When it happens

Trigger: Calling AttributePatch.Create(null) directly, or PatchClassProcessor flows where a helper (e.g. AccessTools.Method/DeclaredMethod) returned null and the result was passed on to Create without a null check.

Common situations: AccessTools.Method returning null because the patch method name/type was misspelled or renamed in a newer library version, then feeding that null into the patch pipeline.

Related errors


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

Appendix: source

Thrown at Harmony/Internal/PatchModels.cs:96

	internal class AttributePatch
	{
		static readonly HarmonyPatchType[] allPatchTypes = [
			HarmonyPatchType.Prefix,
			HarmonyPatchType.Postfix,
			HarmonyPatchType.Transpiler,
			HarmonyPatchType.Finalizer,
			HarmonyPatchType.ReversePatch,
			HarmonyPatchType.InnerPrefix,
			HarmonyPatchType.InnerPostfix
		];

		internal HarmonyMethod info;
		internal HarmonyPatchType? type;

		internal static AttributePatch Create(MethodInfo patch)
		{
			if (patch is null)
				throw new NullReferenceException("Patch method cannot be null");

			var allAttributes = patch.GetCustomAttributes(true);
			var methodName = patch.Name;
			var type = GetPatchType(methodName, allAttributes);
			if (type is null)
				return null;

			if (type != HarmonyPatchType.ReversePatch && patch.IsStatic is false)
				throw new ArgumentException("Patch method " + patch.FullDescription() + " must be static");

			var list = allAttributes
				.Where(attr => attr.GetType().BaseType.FullName == PatchTools.harmonyAttributeFullName)
				.Select(attr =>
				{
					var f_info = AccessTools.Field(attr.GetType(), nameof(HarmonyAttribute.info));
					return f_info.GetValue(attr);
				})
				.Select(AccessTools.MakeDeepCopy<HarmonyMethod>)

View on GitHub (pinned to e7872dc170)