{"record":{"id":"87c9efb82ceb198d","repo":"pardeike/Harmony","slug":"value-cannot-be-null-parameter-method","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'method')","messagePattern":"Value cannot be null\\. \\(Parameter 'method'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCopier.cs","lineNumber":46,"sourceCode":"\t\t\tif (config.MethodBase is null)\r\n\t\t\t\tthrow new ArgumentNullException(\"config.methodbase\");\r\n\t\t\treader = new MethodBodyReader(config.MethodBase, config.il);\r\n\t\t\treader.DeclareVariables(config.originalVariables);\r\n\t\t\treader.GenerateInstructions();\r\n\t\t\treader.SetDebugging(config.debug);\r\n\t\t}\r\n\r\n\t\tinternal void AddTranspiler(MethodInfo transpiler) => transpilers.Add(transpiler);\r\n\r\n\t\tinternal List<CodeInstruction> Finalize(bool stripLastReturn, out bool hasReturnCode, out bool methodEndsInDeadCode, List<Label> endLabels)\r\n\t\t\t=> reader.FinalizeILCodes(transpilers, stripLastReturn, out hasReturnCode, out methodEndsInDeadCode, endLabels);\r\n\r\n\t\tinternal static List<CodeInstruction> GetInstructions(ILGenerator generator, MethodBase method, int maxTranspilers)\r\n\t\t{\r\n\t\t\tif (generator is null)\r\n\t\t\t\tthrow new ArgumentNullException(nameof(generator));\r\n\t\t\tif (method is null)\r\n\t\t\t\tthrow new ArgumentNullException(nameof(method));\r\n\r\n\t\t\tvar originalVariables = MethodPatcherTools.DeclareOriginalLocalVariables(generator, method);\r\n\t\t\tvar copier = new MethodCopier(method, generator, originalVariables);\r\n\r\n\t\t\tvar info = Harmony.GetPatchInfo(method);\r\n\t\t\tif (info is not null)\r\n\t\t\t{\r\n\t\t\t\tvar sortedTranspilers = PatchFunctions.GetSortedPatchMethods(method, [.. info.Transpilers], false);\r\n\t\t\t\tfor (var i = 0; i < maxTranspilers && i < sortedTranspilers.Count; i++)\r\n\t\t\t\t\tcopier.AddTranspiler(sortedTranspilers[i]);\r\n\t\t\t}\r\n\r\n\t\t\treturn copier.Finalize(false, out _, out _, null);\r\n\t\t}\r\n\t}\r\n\r\n\tinternal class MethodBodyReader\r\n\t{\r","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCopier.cs#L28-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the reflection lookup so the MethodBase is actually found (correct name, BindingFlags including Static/Instance/NonPublic/Public)","Check for null before calling any Harmony API and fail with a clear message naming the target you intended to patch","If the target may be absent in some game versions, guard the patch application behind a version check and skip gracefully","Verify you are not passing the output of GetPatchInfo or another optional result where a MethodBase is required"],"exampleFix":"// before\nvar m = typeof(Game).GetMethod(\"Update\");\nharmony.Patch(m, prefix: new HarmonyMethod(typeof(P), nameof(P.Pre)));\n// after\nvar m = typeof(Game).GetMethod(\"Update\", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)\n    ?? throw new MissingMethodException(typeof(Game).FullName, \"Update\");\nharmony.Patch(m, prefix: new HarmonyMethod(typeof(P), nameof(P.Pre)));","handlingStrategy":"validation","validationCode":"var target = AccessTools.Method(typeof(Game), \"Update\") ?? throw new MissingMethodException(typeof(Game).FullName, \"Update\");\n// then pass 'target' to harmony.Patch / PatchProcessor","typeGuard":"static MethodInfo RequireMethod(Type t, string name) =>\n    t.GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)\n    ?? throw new InvalidOperationException($\"{t.FullName}.{name} not found\");","tryCatchPattern":null,"preventionTips":["Never pass raw GetMethod results to Harmony without a null check","Use AccessTools.Method which makes intent explicit, and still assert non-null","Wrap patch bootstrap in a startup method that logs each target before patching","Add unit tests that resolve every patch target at startup"],"tags":["harmony","null-argument","reflection"],"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"}