{"record":{"id":"4fd1b44474e6dd62","repo":"pardeike/Harmony","slug":"value-cannot-be-null-parameter-config-original","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'config.original')","messagePattern":"Value cannot be null\\. \\(Parameter 'config\\.original'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCreator.cs","lineNumber":18,"sourceCode":"using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Reflection;\r\nusing System.Reflection.Emit;\r\n\r\nusing static HarmonyLib.Code;\r\n\r\nnamespace HarmonyLib\r\n{\r\n\tinternal class MethodCreator\r\n\t{\r\n\t\tinternal MethodCreatorConfig config;\r\n\r\n\t\tinternal MethodCreator(MethodCreatorConfig config)\r\n\t\t{\r\n\t\t\tif (config.original is null)\r\n\t\t\t\tthrow new ArgumentNullException(\"config.original\");\r\n\t\t\tthis.config = config;\r\n\t\t\tif (config.debug)\r\n\t\t\t{\r\n\t\t\t\tFileLog.LogBuffered($\"### Patch: {config.original.FullDescription()}\");\r\n\t\t\t\tFileLog.FlushBuffer();\r\n\t\t\t}\r\n\t\t\tif (config.Prepare() == false)\r\n\t\t\t\tthrow new Exception(\"Could not create replacement method\");\r\n\t\t}\r\n\r\n\t\tinternal (MethodInfo, Dictionary<int, CodeInstruction>) CreateReplacement()\r\n\t\t{\r\n\t\t\tconfig.originalVariables = this.DeclareOriginalLocalVariables(config.MethodBase);\r\n\t\t\tconfig.localVariables = new VariableState();\r\n\r\n\t\t\tif (config.Fixes.Any() && config.returnType != typeof(void))\r\n\t\t\t{\r\n\t\t\t\tconfig.resultVariable = config.DeclareLocal(config.returnType);\r","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCreator.cs#L1-L36","documentation":"MethodCreator's constructor requires a MethodCreatorConfig whose 'original' (the method being replaced/wrapped) is non-null. This is an internal guard hit when the wrapper-generation pipeline is invoked without a resolved original method — almost always downstream of a null patch target that earlier code let through. It surfaces as ArgumentNullException with parameter name 'config.original'.","triggerScenarios":"Internal wrapper/patch creation where config.original was never set because the MethodBase resolution returned null; calling Harmony patching APIs with a null original MethodInfo that bypassed earlier null guards.","commonSituations":"Mods patching methods found by reflection that no longer exist after a game update; reverse-patch attempts against a null source method; stale cached method references across hot reloads.","solutions":["Validate the patch target is non-null before calling harmony.Patch/PatchProcessor/ReversePatch","Fix the reflection/AccessTools lookup so it resolves the intended method","Log the exact target type+name in your patch bootstrap so null resolution fails loudly at startup"],"exampleFix":"// before\nvar original = AccessTools.Method(typeof(Hud), \"Render\");\nharmony.Patch(original, postfix: postfix); // original may be null\n// after\nvar original = AccessTools.Method(typeof(Hud), \"Render\") ?? throw new InvalidOperationException(\"Hud.Render not found\");\nharmony.Patch(original, postfix: postfix);","handlingStrategy":"validation","validationCode":"if (original is null)\n    throw new InvalidOperationException($\"Refusing to patch: original method not found ({type}.{name})\");","typeGuard":"static MethodBase EnsureTarget(MethodBase? m, string name) =>\n    m ?? throw new InvalidOperationException($\"Patch target '{name}' not found\");","tryCatchPattern":"try { harmony.Patch(original, prefix: prefix); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"config.original\")\n{ Log.Error(\"Patch target was null — check your reflection lookup\"); }","preventionTips":["Assert all patch targets resolve during mod/plugin startup, before gameplay","Use AccessTools and log AccessTools.FailureInfo when a lookup fails","Avoid caching MethodBase across hot reloads","Fail loudly at boot rather than letting null flow into Harmony internals"],"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"}