microsoft/autogen · error · InvalidOperationException

RequestId is null.

Error message

RequestId is null.

What it means

GrpcAgentRuntime.HandleResponse throws InvalidOperationException when an RpcResponse carries a null RequestId. The RequestId is the correlation key used to look up the pending request in _pendingRequests; without it the response cannot be matched, so the handler rejects it (a matched-but-unmatched response would otherwise be silently dropped).

Source

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

            };

            await this._messageRouter.RouteMessageAsync(responseMessage, cancellationToken);
        }
    }

    private async ValueTask HandleResponse(RpcResponse request, 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.RequestId is null)
        {
            throw new InvalidOperationException("RequestId is null.");
        }

        if (_pendingRequests.TryRemove(request.RequestId, out var resultSink))
        {
            var payload = request.Payload;
            var message = payload.ToObject(SerializationRegistry);
            resultSink.SetResult(message);
        }
    }

    private async ValueTask HandlePublish(CloudEvent evt, CancellationToken cancellationToken = default)
    {
        if (evt is null)
        {
            throw new InvalidOperationException("CloudEvent is null.");
        }
        if (evt.ProtoData is null)
        {

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. On the responder, copy the original request.RequestId into the response before sending.
  2. If proxying responses, forward the envelope's RequestId untouched.
  3. In tests, set RequestId to the value used when sending the request.

Example fix

// before (responder)
var resp = new RpcResponse { Payload = result.ToProtobuf(registry) }; // no RequestId

// after
var resp = new RpcResponse { RequestId = request.RequestId, Payload = result.ToProtobuf(registry) };
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(response?.RequestId))
{
    // responder-side fix: echo request.RequestId into the response before sending
}

Type guard

static bool HasRequestId(RpcResponse? r) => !string.IsNullOrEmpty(r?.RequestId);

Prevention

When it happens

Trigger: A responder completes an RPC without echoing back the originating RequestId; correlation metadata lost through proxies or proto mapping; hand-built responses in tests.

Common situations: Custom agent hosts that create RpcResponse from scratch and forget to copy RequestId from the request; middleware rewriting response envelopes; version mismatches where RequestId became optional.

Related errors


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