pardeike/Harmony · error · Exception
Cannot get result from void method
Error message
Cannot get result from void method {original.FullDescription()} What it means
A patch parameter requests the original method's return value (InjectionType.Result, via the RESULT_VAR naming convention such as a `result`/`__result`-style injected parameter). Harmony throws because the original method returns void, so there is no result value to inject. Use the annotation only on methods with a non-void return type.
Solutions
- Remove the result parameter from the patch signature since the target returns void.
- Use a state/local injection or an instance-field/argument injection instead to observe data from a void method.
- Split the patch class so void targets use a separate patch method without a result parameter.
Example fix
// before (target: void Save())
static void Postfix([HarmonyArgument("result")] object result) { ... }
// after
static void Postfix() { ... } Defensive patterns
Strategy: validation
Validate before calling
if (original.ReturnType == typeof(void) && patchUsesResultInjection(patch))
throw new InvalidOperationException("Target is void; remove the result parameter"); Type guard
bool ResultUsable(MethodInfo original) => original.ReturnType != typeof(void);
Try / catch
try { harmony.Patch(original, postfix: new HarmonyMethod(fix)); }
catch (Exception ex) when (ex.Message.Contains("Cannot get result from void method")) { log.Error(ex); } Prevention
- Check original.ReturnType before writing result parameters
- Avoid sharing one patch method across void and non-void targets
- Capture state via __state or arguments instead for void methods
When it happens
Trigger: Annotating/declaring a patch parameter as the result injection (InjectionType.Result) on a patch whose original method has return type void - e.g. patching a `void Process()` method while declaring a result parameter in the patch signature.
Common situations: Reusing a generic patch class across methods where some targets are void; refactoring the target method to void while keeping the old patch signature; copy-pasting a postfix between void and non-void targets.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- No field found at given index in class
- No such field defined in class
- Cannot assign method return type
- Cannot use with non-ref return type of method
- Wrong type of for method . Expected , got
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/3b7dfea1d10cea73.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Internal/MethodCreatorTools.cs:323
codes.Add(paramType.IsByRef ? Ldflda[fieldInfo] : Ldfld[fieldInfo]);
}
continue;
}
if (injectionType == InjectionType.State)
{
var ldlocCode = paramType.IsByRef ? OpCodes.Ldloca : OpCodes.Ldloc;
if (config.localVariables.TryGetValue(patch.DeclaringType?.AssemblyQualifiedName ?? "null", out var stateVar))
codes.Add(new CodeInstruction(ldlocCode, stateVar));
else
codes.Add(Ldnull);
continue;
}
if (injectionType == InjectionType.Result)
{
if (returnType == typeof(void))
throw new Exception($"Cannot get result from void method {original.FullDescription()}");
var resultType = paramType;
if (resultType.IsByRef && returnType.IsByRef is false)
resultType = resultType.GetElementType();
if (resultType.IsAssignableFrom(returnType) is false)
throw new Exception($"Cannot assign method return type {returnType.FullName} to {InjectedParameter.RESULT_VAR} type {resultType.FullName} for method {original.FullDescription()}");
var ldlocCode = paramType.IsByRef && returnType.IsByRef is false ? OpCodes.Ldloca : OpCodes.Ldloc;
if (returnType.IsValueType && paramType == typeof(object).MakeByRefType())
ldlocCode = OpCodes.Ldloc;
codes.Add(new CodeInstruction(ldlocCode, config.GetLocal(InjectionType.Result)));
if (returnType.IsValueType)
{
if (paramType == typeof(object))
codes.Add(Box[returnType]);
else if (paramType == typeof(object).MakeByRefType())
{
codes.Add(Box[returnType]);
tmpObjectVar = config.DeclareLocal(typeof(object));
codes.Add(Stloc[tmpObjectVar]);
View on GitHub (pinned to e7872dc170)