{"record":{"id":"a3c33e19f45606b8","repo":"microsoft/autogen","slug":"method-methodinfo-name-must-return-a-valuetask-o","errorCode":null,"errorMessage":"Method {methodInfo.Name} must return a ValueTask or ValueTask<T>","messagePattern":"Method (.+?) must return a ValueTask or ValueTask<T>","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs","lineNumber":65,"sourceCode":"        {\n            MethodInfo typeEraseAwait = typeof(HandlerInvoker)\n                    .GetMethod(nameof(TypeEraseAwait), BindingFlags.NonPublic | BindingFlags.Static)!\n                    .MakeGenericMethod(methodInfo.ReturnType.GetGenericArguments()[0]);\n\n            getResultAsync = async\n            (object? message, MessageContext messageContext) =>\n            {\n                object valueTask = invocation(message, messageContext)!;\n                object? typelessValueTask = typeEraseAwait.Invoke(null, new object[] { valueTask });\n\n                Debug.Assert(typelessValueTask is ValueTask<object?>);\n\n                return await (ValueTask<object?>)typelessValueTask;\n            };\n        }\n        else\n        {\n            throw new InvalidOperationException($\"Method {methodInfo.Name} must return a ValueTask or ValueTask<T>\");\n        }\n\n        this.Invocation = getResultAsync;\n    }\n\n    private Func<object?, MessageContext, ValueTask<object?>> Invocation { get; }\n\n    public ValueTask<object?> InvokeAsync(object? obj, MessageContext messageContext)\n    {\n        return this.Invocation(obj, messageContext);\n    }\n}\n","sourceCodeStart":47,"sourceCodeEnd":78,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs#L47-L78","documentation":"Thrown by HandlerInvoker when the handler method's return type is neither ValueTask nor ValueTask<T>. The dispatcher type-erases handler results into ValueTask<object?> and requires the ValueTask-based shape; Task-returning or synchronous handlers are rejected at invoker construction time.","triggerScenarios":"An IHandle<T>.HandleAsync implementation declared as `public async Task HandleAsync(...)` or `public void HandleAsync(...)` instead of ValueTask/ValueTask<T>; signature drift after upgrading the framework when handlers changed shape.","commonSituations":"Porting handlers written for a Task-based API; auto-fix or AI tooling rewriting ValueTask to Task; copying sample handlers from an older version.","solutions":["Declare handlers as `public ValueTask HandleAsync(T message, MessageContext ctx)` or `ValueTask<TResult>`","Change Task-returning bodies to `return ValueTask.CompletedTask;` style instead of async Task","After upgrading the framework, recheck handler signatures against the current IHandle<T> contract"],"exampleFix":"// before\npublic async Task HandleAsync(MyMessage msg, MessageContext ctx) { ... }\n\n// after\npublic async ValueTask HandleAsync(MyMessage msg, MessageContext ctx) { ... }","handlingStrategy":"validation","validationCode":"var rt = methodInfo.ReturnType;\nif (!typeof(ValueTask).IsAssignableFrom(rt) && !(rt.IsGenericType && rt.GetGenericTypeDefinition() == typeof(ValueTask<>)))\n    throw new InvalidOperationException($\"{methodInfo.Name} must return ValueTask or ValueTask<T>\");","typeGuard":"static bool IsValueTaskHandler(MethodInfo m)\n{\n    var t = m.ReturnType;\n    return t == typeof(ValueTask) || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ValueTask<>));\n}","tryCatchPattern":"try { new HandlerInvoker(method, target); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"must return a ValueTask\")) { throw new InvalidOperationException($\"Handler {method.Name} signature invalid; change return type to ValueTask\", ex); }","preventionTips":["Declare handlers as ValueTask/ValueTask<T> from the start","Re-check handler signatures after framework upgrades"],"tags":["handlers","signature","valuetask","reflection"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}