pardeike/Harmony · error · Exception

Parameter " " not found in method

Error message

Parameter "{paramRealName}" not found in method {original.FullDescription()}

What it means

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.

Solutions

  1. Correct the patch parameter name to exactly match a parameter of the original method (inspect original.GetParameters()).
  2. Bind by index instead of name (the PARAM_INDEX_PREFIX convention) if names are unstable across versions.
  3. Add a startup validation that all referenced parameter names exist on the target before applying patches.

Example fix

// before (target param is 'playerId')
static void Postfix(int playerID) { ... }

// after
static void Postfix(int playerId) { ... }
Defensive patterns

Strategy: validation

Validate before calling

var names = original.GetParameters().Select(p => p.Name).ToArray();
if (!names.Contains("playerId"))
    throw new InvalidOperationException("Original has no parameter 'playerId'");

Type guard

bool HasOriginalParam(MethodInfo original, string name) =>
    original.GetParameters().Any(p => p.Name == name);

Try / catch

try { harmony.Patch(original, postfix: new HarmonyMethod(fix)); }
catch (Exception ex) when (ex.Message.Contains("not found in method")) { log.Error(ex); }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15). Data as JSON: /api/errors/43f4853aa5ead732. Report an issue: GitHub.

Appendix: source

Thrown at Harmony/Internal/MethodCreatorTools.cs:378

					codes.Add(Ldloca[config.GetLocal(InjectionType.ResultRef)]);

					refResultUsed = true;
					continue;
				}

				if (injection.argumentMode != ArgumentMode.Original && config.localVariables.TryGetValue(paramRealName, out var localBuilder))
				{
					var ldlocCode = paramType.IsByRef ? OpCodes.Ldloca : OpCodes.Ldloc;
					codes.Add(new CodeInstruction(ldlocCode, localBuilder));
					continue;
				}

				int argumentIdx;
				if (injection.argumentMode == ArgumentMode.Original)
				{
					argumentIdx = Array.IndexOf(originalParameterNames, paramRealName);
					if (argumentIdx == -1)
						throw new Exception($"Parameter \"{paramRealName}\" not found in method {original.FullDescription()}");
				}
				else if (paramRealName.StartsWith(PARAM_INDEX_PREFIX, StringComparison.Ordinal))
				{
					var val = paramRealName.Substring(PARAM_INDEX_PREFIX.Length);
					if (!int.TryParse(val, out argumentIdx))
						throw new Exception($"Parameter {paramRealName} does not contain a valid index");
					if (argumentIdx < 0 || argumentIdx >= originalParameters.Length)
						throw new Exception($"No parameter found at index {argumentIdx}");
				}
				else
				{
					argumentIdx = patch.GetArgumentIndex(originalParameterNames, injection.parameterInfo);
					if (argumentIdx == -1)
					{
						var harmonyMethod = HarmonyMethodExtensions.GetMergedFromType(paramType);
						harmonyMethod.methodType ??= MethodType.Normal;
						var delegateOriginal = harmonyMethod.GetOriginalMethod();
						if (delegateOriginal is MethodInfo methodInfo)

View on GitHub (pinned to e7872dc170)