{"record":{"id":"0039ad430c7b7111","repo":"pardeike/Harmony","slug":"parameter-paramrealname-does-not-contain-a-valid-index","errorCode":null,"errorMessage":"Parameter {paramRealName} does not contain a valid index","messagePattern":"Parameter (.+?) does not contain a valid index","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCreatorTools.cs","lineNumber":384,"sourceCode":"\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\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvar delegateConstructor = paramType.GetConstructor([typeof(object), typeof(IntPtr)]);\r\n\t\t\t\t\t\t\tif (delegateConstructor is not null)\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tif (methodInfo.IsStatic)\r\n\t\t\t\t\t\t\t\t\tcodes.Add(Ldnull);\r","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCreatorTools.cs#L366-L402","documentation":"A patch parameter uses index-based argument binding (name starting with PARAM_INDEX_PREFIX, e.g. `__0`). The text after the prefix must parse as an int; Harmony throws this Exception when int.TryParse fails. It indicates a malformed index-based parameter name in the patch signature.","triggerScenarios":"Writing an index-prefixed patch parameter whose suffix is not a valid integer, e.g. `__abc`, `__0x1`, or a name where the prefix collides with a user parameter name that happens to start with the prefix.","commonSituations":"Typos in hand-written patch signatures; code generation emitting malformed names; accidentally prefixing a normal parameter name with the index marker.","solutions":["Use a plain decimal index after the prefix, e.g. `__0`, `__1`.","Bind by original parameter name instead of index to avoid format issues.","Sanitize generated patch parameter names to ensure the suffix after the prefix is digits only."],"exampleFix":"// before\nstatic void Postfix(int __first) { ... }\n\n// after\nstatic void Postfix(int __0) { ... }","handlingStrategy":"validation","validationCode":"if (name.StartsWith(\"__\") && !int.TryParse(name.Substring(2), out _))\n    throw new ArgumentException($\"Bad index parameter name: {name}\");","typeGuard":"bool IsWellFormedIndexParam(string name) =>\n    name.StartsWith(\"__\") && int.TryParse(name.Substring(2), out var i) && i >= 0;","tryCatchPattern":"try { harmony.Patch(original, postfix: new HarmonyMethod(fix)); }\ncatch (Exception ex) when (ex.Message.Contains(\"does not contain a valid index\")) { log.Error(ex); }","preventionTips":["Only digits after the index prefix","Validate generated patch signatures in unit tests","Prefer name-based binding when indexes are unclear"],"tags":["harmony","argument-binding","invalid-format","parameter-index"],"backgroundTag":"invalid-argument-format","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"}