microsoft/autogen · error · InvalidOperationException

Target is null.

Error message

Target is null.

What it means

GrpcAgentRuntime.HandleRequest throws InvalidOperationException when an incoming RpcRequest has a null Target. Without a target AgentId the runtime cannot resolve EnsureAgentAsync, so the request is rejected before payload deserialization.

Source

Thrown at dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentRuntime.cs:154

    public void Dispose()
    {
        this._shutdownCts.Cancel();
        this._messageRouter.Dispose();
    }

    private async ValueTask HandleRequest(RpcRequest request, CancellationToken cancellationToken = default)
    {
        if (request is null)
        {
            throw new InvalidOperationException("Request is null.");
        }
        if (request.Payload is null)
        {
            throw new InvalidOperationException("Payload is null.");
        }
        if (request.Target is null)
        {
            throw new InvalidOperationException("Target is null.");
        }

        var agentId = request.Target;
        var agent = await this._agentsContainer.EnsureAgentAsync(agentId.FromProtobuf());

        // Convert payload back to object
        var payload = request.Payload;
        var message = payload.ToObject(SerializationRegistry);

        var messageContext = new MessageContext(request.RequestId, cancellationToken)
        {

            Sender = request.Source?.FromProtobuf() ?? null,
            Topic = null,
            IsRpc = true
        };

        var result = await agent.OnMessageAsync(message, messageContext);

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Set Target on every RpcRequest (map from the recipient AgentId via ToProtobuf) at the send site.
  2. Use the publish path (CloudEvent/HandlePublish) for broadcasts that have no single target.
  3. Align proto/AgentId mapping helpers between sender and receiver versions.

Example fix

// before
var req = new RpcRequest { Payload = payload, RequestId = rid }; // no Target

// after
var req = new RpcRequest
{
    Target = recipient.ToProtobuf(),
    Payload = payload,
    RequestId = rid,
};
Defensive patterns

Strategy: validation

Validate before calling

if (request?.Target is null)
{
    // sender bug: set Target = recipient.ToProtobuf() before dispatch
}

Type guard

static bool HasTarget(RpcRequest? r) => r?.Target is not null;

Prevention

When it happens

Trigger: RpcRequest arrives with Payload set but Target unset — sender built the request without assigning the destination agent, or the target was lost in translation between Contracts.AgentId and protobuf mapping.

Common situations: Fire-and-forget/publish-style code mistakenly routed through the request path without a destination; refactors where request.Target = recipient.ToProtobuf() was dropped; address fields renamed between proto versions; tests constructing requests by hand.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/2966886b3c10e12e. Report an issue: GitHub.