{"record":{"id":"81536cbd189c5344","repo":"microsoft/autogen","slug":"target-must-be-provided-for-non-static-methods","errorCode":null,"errorMessage":"Target must be provided for non-static methods","messagePattern":"Target must be provided for non-static methods","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs","lineNumber":33,"sourceCode":"        return await vt;\n    }\n\n    public HandlerInvoker(MethodInfo methodInfo, object? target = null)\n    {\n        // TODO: Check that the MethodInfo params check out?\n\n        Func<object?, MessageContext, object?> invocation;\n        if (target != null)\n        {\n            invocation = (object? message, MessageContext messageContext) => methodInfo.Invoke(target, new object?[] { message, messageContext });\n        }\n        else if (methodInfo.IsStatic)\n        {\n            invocation = (object? message, MessageContext messageContext) => methodInfo.Invoke(null, new object?[] { message, messageContext });\n        }\n        else\n        {\n            throw new InvalidOperationException(\"Target must be provided for non-static methods\");\n        }\n\n        Func<object?, MessageContext, ValueTask<object?>> getResultAsync;\n        if (methodInfo.ReturnType.IsAssignableFrom(typeof(ValueTask)))\n        {\n            getResultAsync = async\n            (object? message, MessageContext messageContext) =>\n            {\n                await (ValueTask)invocation(message, messageContext)!;\n                return null;\n            };\n        }\n        else if (methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))\n        {\n            MethodInfo typeEraseAwait = typeof(HandlerInvoker)\n                    .GetMethod(nameof(TypeEraseAwait), BindingFlags.NonPublic | BindingFlags.Static)!\n                    .MakeGenericMethod(methodInfo.ReturnType.GetGenericArguments()[0]);\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs#L15-L51","documentation":"Thrown by HandlerInvoker's constructor when a non-static MethodInfo is supplied without a target instance to invoke it on. HandlerInvoker wraps a reflected handler method; instance methods require the agent object as target, static methods can be invoked with null. In framework code the target is always the agent, so this guards custom/misuse construction.","triggerScenarios":"Constructing new HandlerInvoker(instanceMethodInfo, target: null) for a method that is not static; passing a MethodInfo obtained from a different (non-static) member while building custom dispatch plumbing.","commonSituations":"Custom message dispatch layers reusing HandlerInvoker with reflection code that loses the target; refactor changing a handler from static to instance while custom wiring still passes null.","solutions":["Pass the owning agent instance as target when the method is an instance method","Keep handler methods static only if you will invoke them without a target","Prefer letting BaseAgent build invokers itself rather than constructing HandlerInvoker manually"],"exampleFix":"// before\nvar invoker = new HandlerInvoker(typeof(MyAgent).GetMethod(nameof(MyAgent.HandleAsync))!, null); // instance method, no target\n\n// after\nvar invoker = new HandlerInvoker(typeof(MyAgent).GetMethod(nameof(MyAgent.HandleAsync))!, agentInstance);","handlingStrategy":"validation","validationCode":"if (!methodInfo.IsStatic && target is null) throw new InvalidOperationException($\"Instance method {methodInfo.Name} requires a target\");","typeGuard":null,"tryCatchPattern":"try { new HandlerInvoker(methodInfo, target); } catch (InvalidOperationException ex) when (ex.Message == \"Target must be provided for non-static methods\") { throw new InvalidOperationException($\"Handler {methodInfo.Name} must be static or given the agent instance\", ex); }","preventionTips":["Always pass the agent instance for instance handlers","Let BaseAgent construct invokers; avoid manual HandlerInvoker wiring"],"tags":["reflection","handlers","invocation"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}