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
- Verify the sender sets Payload via the serialization registry before dispatching (check SendRequest construction).
- Align serialization registries/proto versions between sender and receiver so payloads are populated.
- 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
- Always build RpcRequest with Payload = message.ToProtobuf(registry) at the send site.
- Route body-less notifications through the publish path, not the request path.
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
- Request is null.
- Target is null.
- RequestId is null.
- CloudEvent is null.
- Request message is missing a target. Message: '{request}'.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/f3e63a9f640a0020.
Report an issue: GitHub.