{"record":{"id":"ab7cda22a3167e52","repo":"pardeike/Harmony","slug":"cannot-assign-method-return-type-returntype-fullname-to","errorCode":null,"errorMessage":"Cannot assign method return type {returnType.FullName} to {InjectedParameter.RESULT_VAR} type {resultType.FullName} for method {original.FullDescription()}","messagePattern":"Cannot assign method return type (.+?) to (.+?) type (.+?) for method (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCreatorTools.cs","lineNumber":328,"sourceCode":"\t\t\t\tif (injectionType == InjectionType.State)\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\tif (config.localVariables.TryGetValue(patch.DeclaringType?.AssemblyQualifiedName ?? \"null\", out var stateVar))\r\n\t\t\t\t\t\tcodes.Add(new CodeInstruction(ldlocCode, stateVar));\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tcodes.Add(Ldnull);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (injectionType == InjectionType.Result)\r\n\t\t\t\t{\r\n\t\t\t\t\tif (returnType == typeof(void))\r\n\t\t\t\t\t\tthrow new Exception($\"Cannot get result from void method {original.FullDescription()}\");\r\n\t\t\t\t\tvar resultType = paramType;\r\n\t\t\t\t\tif (resultType.IsByRef && returnType.IsByRef is false)\r\n\t\t\t\t\t\tresultType = resultType.GetElementType();\r\n\t\t\t\t\tif (resultType.IsAssignableFrom(returnType) is false)\r\n\t\t\t\t\t\tthrow new Exception($\"Cannot assign method return type {returnType.FullName} to {InjectedParameter.RESULT_VAR} type {resultType.FullName} for method {original.FullDescription()}\");\r\n\t\t\t\t\tvar ldlocCode = paramType.IsByRef && returnType.IsByRef is false ? OpCodes.Ldloca : OpCodes.Ldloc;\r\n\t\t\t\t\tif (returnType.IsValueType && paramType == typeof(object).MakeByRefType())\r\n\t\t\t\t\t\tldlocCode = OpCodes.Ldloc;\r\n\t\t\t\t\tcodes.Add(new CodeInstruction(ldlocCode, config.GetLocal(InjectionType.Result)));\r\n\t\t\t\t\tif (returnType.IsValueType)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tif (paramType == typeof(object))\r\n\t\t\t\t\t\t\tcodes.Add(Box[returnType]);\r\n\t\t\t\t\t\telse if (paramType == typeof(object).MakeByRefType())\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tcodes.Add(Box[returnType]);\r\n\t\t\t\t\t\t\ttmpObjectVar = config.DeclareLocal(typeof(object));\r\n\t\t\t\t\t\t\tcodes.Add(Stloc[tmpObjectVar]);\r\n\t\t\t\t\t\t\tcodes.Add(Ldloca[tmpObjectVar]);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCreatorTools.cs#L310-L346","documentation":"The patch requests the original's return value (InjectionType.Result), but the declared type of the injected parameter is not assignable from the original method's return type. Harmony validates `resultType.IsAssignableFrom(returnType)` before emitting the load of the result local and throws when types are incompatible, preventing invalid IL.","triggerScenarios":"Declaring a result-injected parameter of a type that the original's return type cannot be assigned to, e.g. `string` result parameter on a method returning `int`, or an unboxed value-type parameter for a boxed/object return.","commonSituations":"Target method return type changed between versions (int -> long, T -> object); patch shared across overloads with different return types; using `ref`/`out` parameter forms that don't match the result type rules.","solutions":["Change the injected result parameter's type to exactly the original method's return type (or a compatible base/interface).","Use `object` and box manually if you need a generic patch, respecting value-type handling.","Verify original.FullDescription() return type at patch-application time and pick/branch to the right patch method."],"exampleFix":"// before (target returns int)\nstatic void Postfix([HarmonyArgument(\"result\")] string result) { ... }\n\n// after\nstatic void Postfix([HarmonyArgument(\"result\")] int result) { ... }","handlingStrategy":"type-guard","validationCode":"var paramType = resultParam.ParameterType;\nif (!paramType.IsAssignableFrom(original.ReturnType))\n    throw new InvalidOperationException($\"Result param {paramType} cannot accept {original.ReturnType}\");","typeGuard":"bool ResultTypeMatches(MethodInfo original, ParameterInfo p) =>\n    p.ParameterType.IsAssignableFrom(original.ReturnType);","tryCatchPattern":"try { harmony.Patch(original, postfix: new HarmonyMethod(fix)); }\ncatch (Exception ex) when (ex.Message.Contains(\"Cannot assign method return type\")) { log.Error(ex); }","preventionTips":["Type the result parameter exactly as the target's return type","Re-check signatures when target return types change","Test patches against the exact target assembly version"],"tags":["harmony","type-mismatch","injection","return-type"],"backgroundTag":"type-mismatch","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"}