microsoft/autogen · error · InvalidOperationException
Target must be provided for non-static methods
Error message
Target must be provided for non-static methods
What it means
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.
Source
Thrown at dotnet/src/Microsoft.AutoGen/Core/HandlerInvoker.cs:33
return await vt;
}
public HandlerInvoker(MethodInfo methodInfo, object? target = null)
{
// TODO: Check that the MethodInfo params check out?
Func<object?, MessageContext, object?> invocation;
if (target != null)
{
invocation = (object? message, MessageContext messageContext) => methodInfo.Invoke(target, new object?[] { message, messageContext });
}
else if (methodInfo.IsStatic)
{
invocation = (object? message, MessageContext messageContext) => methodInfo.Invoke(null, new object?[] { message, messageContext });
}
else
{
throw new InvalidOperationException("Target must be provided for non-static methods");
}
Func<object?, MessageContext, ValueTask<object?>> getResultAsync;
if (methodInfo.ReturnType.IsAssignableFrom(typeof(ValueTask)))
{
getResultAsync = async
(object? message, MessageContext messageContext) =>
{
await (ValueTask)invocation(message, messageContext)!;
return null;
};
}
else if (methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))
{
MethodInfo typeEraseAwait = typeof(HandlerInvoker)
.GetMethod(nameof(TypeEraseAwait), BindingFlags.NonPublic | BindingFlags.Static)!
.MakeGenericMethod(methodInfo.ReturnType.GetGenericArguments()[0]);
View on GitHub (pinned to 027ecf0a37)
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
Example fix
// before var invoker = new HandlerInvoker(typeof(MyAgent).GetMethod(nameof(MyAgent.HandleAsync))!, null); // instance method, no target // after var invoker = new HandlerInvoker(typeof(MyAgent).GetMethod(nameof(MyAgent.HandleAsync))!, agentInstance);
Defensive patterns
Strategy: validation
Validate before calling
if (!methodInfo.IsStatic && target is null) throw new InvalidOperationException($"Instance method {methodInfo.Name} requires a target"); Try / catch
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); } Prevention
- Always pass the agent instance for instance handlers
- Let BaseAgent construct invokers; avoid manual HandlerInvoker wiring
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- No handler method found for interface {interface_.FullName}
- Method {methodInfo.Name} must return a ValueTask or ValueTas
- Could not create chat manager
- Could not create chat manager; make sure that it contains a
- Failed to create instance of {input.FullName}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/81536cbd189c5344.
Report an issue: GitHub.