{"record":{"id":"43f4853aa5ead732","repo":"pardeike/Harmony","slug":"parameter-paramrealname-not-found-in-method-original","errorCode":null,"errorMessage":"Parameter \"{paramRealName}\" not found in method {original.FullDescription()}","messagePattern":"Parameter \"(.+?)\" not found in method (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCreatorTools.cs","lineNumber":378,"sourceCode":"\t\t\t\t\tcodes.Add(Ldloca[config.GetLocal(InjectionType.ResultRef)]);\r\n\r\n\t\t\t\t\trefResultUsed = true;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (injection.argumentMode != ArgumentMode.Original && config.localVariables.TryGetValue(paramRealName, out var localBuilder))\r\n\t\t\t\t{\r\n\t\t\t\t\tvar ldlocCode = paramType.IsByRef ? OpCodes.Ldloca : OpCodes.Ldloc;\r\n\t\t\t\t\tcodes.Add(new CodeInstruction(ldlocCode, localBuilder));\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tint argumentIdx;\r\n\t\t\t\tif (injection.argumentMode == ArgumentMode.Original)\r\n\t\t\t\t{\r\n\t\t\t\t\targumentIdx = Array.IndexOf(originalParameterNames, paramRealName);\r\n\t\t\t\t\tif (argumentIdx == -1)\r\n\t\t\t\t\t\tthrow new Exception($\"Parameter \\\"{paramRealName}\\\" not found in method {original.FullDescription()}\");\r\n\t\t\t\t}\r\n\t\t\t\telse if (paramRealName.StartsWith(PARAM_INDEX_PREFIX, StringComparison.Ordinal))\r\n\t\t\t\t{\r\n\t\t\t\t\tvar val = paramRealName.Substring(PARAM_INDEX_PREFIX.Length);\r\n\t\t\t\t\tif (!int.TryParse(val, out argumentIdx))\r\n\t\t\t\t\t\tthrow new Exception($\"Parameter {paramRealName} does not contain a valid index\");\r\n\t\t\t\t\tif (argumentIdx < 0 || argumentIdx >= originalParameters.Length)\r\n\t\t\t\t\t\tthrow new Exception($\"No parameter found at index {argumentIdx}\");\r\n\t\t\t\t}\r\n\t\t\t\telse\r\n\t\t\t\t{\r\n\t\t\t\t\targumentIdx = patch.GetArgumentIndex(originalParameterNames, injection.parameterInfo);\r\n\t\t\t\t\tif (argumentIdx == -1)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tvar harmonyMethod = HarmonyMethodExtensions.GetMergedFromType(paramType);\r\n\t\t\t\t\t\tharmonyMethod.methodType ??= MethodType.Normal;\r\n\t\t\t\t\t\tvar delegateOriginal = harmonyMethod.GetOriginalMethod();\r\n\t\t\t\t\t\tif (delegateOriginal is MethodInfo methodInfo)\r","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCreatorTools.cs#L360-L396","documentation":"A patch parameter uses ArgumentMode.Original, meaning it binds by the original method's parameter name. Harmony searches originalParameterNames with Array.IndexOf and throws this Exception when the name is not found (-1). The parameter name in the patch must exactly match a parameter of the target method.","triggerScenarios":"Naming an injected patch parameter after an original parameter that does not exist (typo, renamed in a target update, patching an overload with different parameter names, or referencing the target's parameter names case-sensitively).","commonSituations":"Target library refactor renamed parameters; patch written against documentation where the parameter had a different name; using the annotation/marker-based injection convention with a stale name.","solutions":["Correct the patch parameter name to exactly match a parameter of the original method (inspect original.GetParameters()).","Bind by index instead of name (the PARAM_INDEX_PREFIX convention) if names are unstable across versions.","Add a startup validation that all referenced parameter names exist on the target before applying patches."],"exampleFix":"// before (target param is 'playerId')\nstatic void Postfix(int playerID) { ... }\n\n// after\nstatic void Postfix(int playerId) { ... }","handlingStrategy":"validation","validationCode":"var names = original.GetParameters().Select(p => p.Name).ToArray();\nif (!names.Contains(\"playerId\"))\n    throw new InvalidOperationException(\"Original has no parameter 'playerId'\");","typeGuard":"bool HasOriginalParam(MethodInfo original, string name) =>\n    original.GetParameters().Any(p => p.Name == name);","tryCatchPattern":"try { harmony.Patch(original, postfix: new HarmonyMethod(fix)); }\ncatch (Exception ex) when (ex.Message.Contains(\"not found in method\")) { log.Error(ex); }","preventionTips":["Bind by index for name-unstable targets","Diff target parameter names on every update","Use nameof-like constants sourced from decompiled metadata"],"tags":["harmony","argument-binding","parameter-name"],"backgroundTag":"missing-required-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"}