microsoft/autogen · error · InvalidOperationException

Payload is null.

Error message

Payload is null.

What it means

GrpcAgentRuntime.HandleRequest throws InvalidOperationException when an incoming RpcRequest carries a null Payload. Even with a valid Target, a request without a payload cannot be deserialized to a message, so the handler rejects it before agent resolution.

Source

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

    private readonly bool _strictMessageDeserialization;
    public IProtoSerializationRegistry SerializationRegistry { get; } = new ProtobufSerializationRegistry();

    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,

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Verify the sender sets Payload via the serialization registry before dispatching (check SendRequest construction).
  2. Align serialization registries/proto versions between sender and receiver so payloads are populated.
  3. If the message intentionally has no body, send an explicit empty-but-present payload type the receiver understands.

Example fix

// before
var req = new RpcRequest { Target = target.ToProtobuf(), RequestId = rid }; // no Payload

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

Strategy: validation

Validate before calling

if (request?.Payload is null)
{
    // reject at the send site instead: always serialize the message body before dispatch
}

Type guard

static bool HasPayload(RpcRequest? r) => r?.Payload is not null;

Prevention

When it happens

Trigger: RpcRequest arrives with Target set but Payload unset — a client that sends an invocation without serializing a message body, a proto where payload was dropped (optional field omitted), or a hand-built request in tests.

Common situations: SendMessage paths that serialize to the wrong registry and silently produce an empty payload; partial construction of RpcRequest after a refactor; interop with non-.NET clients that do not populate payload; version differences making Payload optional.

Related errors


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