{"record":{"id":"27fe6b428d761951","repo":"pardeike/Harmony","slug":"value-cannot-be-null-parameter-frommethod","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'fromMethod')","messagePattern":"Value cannot be null\\. \\(Parameter 'fromMethod'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCopier.cs","lineNumber":20,"sourceCode":"using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Reflection;\r\nusing System.Reflection.Emit;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.InteropServices;\r\n\r\nnamespace HarmonyLib\r\n{\r\n\tinternal class MethodCopier\r\n\t{\r\n\t\treadonly MethodBodyReader reader;\r\n\t\treadonly List<MethodInfo> transpilers = [];\r\n\r\n\t\tinternal MethodCopier(MethodBase fromMethod, ILGenerator toILGenerator, LocalBuilder[] existingVariables = null)\r\n\t\t{\r\n\t\t\tif (fromMethod is null)\r\n\t\t\t\tthrow new ArgumentNullException(nameof(fromMethod));\r\n\t\t\treader = new MethodBodyReader(fromMethod, toILGenerator);\r\n\t\t\treader.DeclareVariables(existingVariables);\r\n\t\t\treader.GenerateInstructions();\r\n\t\t}\r\n\r\n\t\tinternal MethodCopier(MethodCreatorConfig config)\r\n\t\t{\r\n\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","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCopier.cs#L2-L38","documentation":"MethodCopier copies the IL body of one method into an ILGenerator. The primary constructor requires the source MethodBase; passing null is caught immediately with ArgumentNullException('fromMethod') before any body reading begins.","triggerScenarios":"Calling MethodCopier(null, ilGenerator) or internal copy paths (e.g. patch/mini-copy helpers) where the resolved source method (from PatchFunctions/GetOriginalMethod chains) came back null — commonly when an original method lookup by name/type failed upstream and the null flowed into the copier.","commonSituations":"AccessTools.Method returned null because of a typo'd name or signature mismatch, then the result was passed on to Harmony's copy machinery; patching a method that was stripped by trimming/IL2CPP; building dynamic replacement methods with a null source.","solutions":["Verify the source method reference is non-null before constructing the copier (check the result of AccessTools.Method/Type.GetMethod)","Fix the method lookup — name, BindingFlags, and parameter types must match the real method","Confirm the target method exists in the assembly and is not trimmed away","If null is legitimately possible, fall back to emitting new IL instead of copying"],"exampleFix":"// before\nvar copier = new MethodCopier(AccessTools.Method(typeof(Foo), \"Baar\"), il); // Baar typo → null\n// after\nvar src = AccessTools.Method(typeof(Foo), \"Bar\") ?? throw new InvalidOperationException(\"Bar not found\");\nvar copier = new MethodCopier(src, il);","handlingStrategy":"validation","validationCode":"var src = AccessTools.Method(typeof(Target), \"MethodName\");\nif (src is null) throw new InvalidOperationException(\"Source method not found — fix name/signature before copying IL\");","typeGuard":"static MethodInfo? FindMethod(Type t, string name) => t.GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);","tryCatchPattern":"try { var copier = new MethodCopier(src, il); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"fromMethod\") { /* method lookup failed — resolve before retry */ }","preventionTips":["Always null-check the result of AccessTools.Method/GetMethod before passing it on","Log the lookup target (type + method name) when resolving source methods","Do not patch types that may be trimmed out of the assembly"],"tags":["null-argument","il-copy","reflection","harmony"],"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"}