{"record":{"id":"cec53a74efcdc750","repo":"pardeike/Harmony","slug":"patch-method-cannot-be-null","errorCode":null,"errorMessage":"Patch method cannot be null","messagePattern":"Patch method cannot be null","errorType":"exception","errorClass":"NullReferenceException","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/PatchModels.cs","lineNumber":96,"sourceCode":"\tinternal class AttributePatch\r\n\t{\r\n\t\tstatic readonly HarmonyPatchType[] allPatchTypes = [\r\n\t\t\tHarmonyPatchType.Prefix,\r\n\t\t\tHarmonyPatchType.Postfix,\r\n\t\t\tHarmonyPatchType.Transpiler,\r\n\t\t\tHarmonyPatchType.Finalizer,\r\n\t\t\tHarmonyPatchType.ReversePatch,\r\n\t\t\tHarmonyPatchType.InnerPrefix,\r\n\t\t\tHarmonyPatchType.InnerPostfix\r\n\t\t];\r\n\r\n\t\tinternal HarmonyMethod info;\r\n\t\tinternal HarmonyPatchType? type;\r\n\r\n\t\tinternal static AttributePatch Create(MethodInfo patch)\r\n\t\t{\r\n\t\t\tif (patch is null)\r\n\t\t\t\tthrow new NullReferenceException(\"Patch method cannot be null\");\r\n\r\n\t\t\tvar allAttributes = patch.GetCustomAttributes(true);\r\n\t\t\tvar methodName = patch.Name;\r\n\t\t\tvar type = GetPatchType(methodName, allAttributes);\r\n\t\t\tif (type is null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tif (type != HarmonyPatchType.ReversePatch && patch.IsStatic is false)\r\n\t\t\t\tthrow new ArgumentException(\"Patch method \" + patch.FullDescription() + \" must be static\");\r\n\r\n\t\t\tvar list = allAttributes\r\n\t\t\t\t.Where(attr => attr.GetType().BaseType.FullName == PatchTools.harmonyAttributeFullName)\r\n\t\t\t\t.Select(attr =>\r\n\t\t\t\t{\r\n\t\t\t\t\tvar f_info = AccessTools.Field(attr.GetType(), nameof(HarmonyAttribute.info));\r\n\t\t\t\t\treturn f_info.GetValue(attr);\r\n\t\t\t\t})\r\n\t\t\t\t.Select(AccessTools.MakeDeepCopy<HarmonyMethod>)\r","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/PatchModels.cs#L78-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the MethodInfo lookup before creating the patch: assert AccessTools.Method returned non-null.","Use AccessTools.Method(typeof(PatchClass), nameof(PatchClass.Prefix)) so renaming breaks at compile time.","Null-check lookups and log a clear message instead of passing null into Harmony APIs."],"exampleFix":"// before\nAttributePatch.Create(AccessTools.Method(typeof(P), \"Preffix\")); // null: typo\n\n// after\nvar patch = AccessTools.Method(typeof(P), nameof(P.Prefix));\nif (patch is null) throw new InvalidOperationException(\"Patch method missing\");\nAttributePatch.Create(patch);","handlingStrategy":"validation","validationCode":"var patch = AccessTools.Method(typeof(MyPatches), nameof(MyPatches.Prefix));\nif (patch is null)\n    throw new InvalidOperationException(\"Patch method not found — check name/signature\");","typeGuard":"static MethodInfo RequireMethod(Type t, string name) =>\n    AccessTools.Method(t, name) ?? throw new InvalidOperationException($\"{t.Name}.{name} not found\");","tryCatchPattern":"try { AttributePatch.Create(patch); }\ncatch (NullReferenceException ex) when (ex.Message.Contains(\"Patch method cannot be null\"))\n{ Logger.Error(\"Patch MethodInfo was null\"); }","preventionTips":["Use nameof() for patch method lookups instead of string literals.","Assert non-null from AccessTools lookups immediately after calling them.","Check Harmony patches after target-library updates since renames silently null out lookups."],"tags":["harmony","patch-annotation","null-argument"],"backgroundTag":"null-argument","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"}