{"record":{"id":"358dae8052d9f04f","repo":"microsoft/autogen","slug":"requestid-is-null","errorCode":null,"errorMessage":"RequestId is null.","messagePattern":"RequestId is null\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentRuntime.cs","lineNumber":203,"sourceCode":"            };\n\n            await this._messageRouter.RouteMessageAsync(responseMessage, cancellationToken);\n        }\n    }\n\n    private async ValueTask HandleResponse(RpcResponse request, CancellationToken _ = default)\n    {\n        if (request is null)\n        {\n            throw new InvalidOperationException(\"Request is null.\");\n        }\n        if (request.Payload is null)\n        {\n            throw new InvalidOperationException(\"Payload is null.\");\n        }\n        if (request.RequestId is null)\n        {\n            throw new InvalidOperationException(\"RequestId is null.\");\n        }\n\n        if (_pendingRequests.TryRemove(request.RequestId, out var resultSink))\n        {\n            var payload = request.Payload;\n            var message = payload.ToObject(SerializationRegistry);\n            resultSink.SetResult(message);\n        }\n    }\n\n    private async ValueTask HandlePublish(CloudEvent evt, CancellationToken cancellationToken = default)\n    {\n        if (evt is null)\n        {\n            throw new InvalidOperationException(\"CloudEvent is null.\");\n        }\n        if (evt.ProtoData is null)\n        {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentRuntime.cs#L185-L221","documentation":"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).","triggerScenarios":"A responder completes an RPC without echoing back the originating RequestId; correlation metadata lost through proxies or proto mapping; hand-built responses in tests.","commonSituations":"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.","solutions":["On the responder, copy the original request.RequestId into the response before sending.","If proxying responses, forward the envelope's RequestId untouched.","In tests, set RequestId to the value used when sending the request."],"exampleFix":"// before (responder)\nvar resp = new RpcResponse { Payload = result.ToProtobuf(registry) }; // no RequestId\n\n// after\nvar resp = new RpcResponse { RequestId = request.RequestId, Payload = result.ToProtobuf(registry) };","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(response?.RequestId))\n{\n    // responder-side fix: echo request.RequestId into the response before sending\n}","typeGuard":"static bool HasRequestId(RpcResponse? r) => !string.IsNullOrEmpty(r?.RequestId);","tryCatchPattern":null,"preventionTips":["Always copy RequestId from the incoming request into the outgoing RpcResponse.","Forward correlation ids untouched through any proxy/interceptor middleware."],"tags":["grpc","wire-protocol","correlation","rpc-response"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}