{"record":{"id":"2966886b3c10e12e","repo":"microsoft/autogen","slug":"target-is-null","errorCode":null,"errorMessage":"Target is null.","messagePattern":"Target is null\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentRuntime.cs","lineNumber":154,"sourceCode":"    public void Dispose()\n    {\n        this._shutdownCts.Cancel();\n        this._messageRouter.Dispose();\n    }\n\n    private async ValueTask HandleRequest(RpcRequest request, CancellationToken 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.Target is null)\n        {\n            throw new InvalidOperationException(\"Target is null.\");\n        }\n\n        var agentId = request.Target;\n        var agent = await this._agentsContainer.EnsureAgentAsync(agentId.FromProtobuf());\n\n        // Convert payload back to object\n        var payload = request.Payload;\n        var message = payload.ToObject(SerializationRegistry);\n\n        var messageContext = new MessageContext(request.RequestId, cancellationToken)\n        {\n\n            Sender = request.Source?.FromProtobuf() ?? null,\n            Topic = null,\n            IsRpc = true\n        };\n\n        var result = await agent.OnMessageAsync(message, messageContext);","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentRuntime.cs#L136-L172","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set Target on every RpcRequest (map from the recipient AgentId via ToProtobuf) at the send site.","Use the publish path (CloudEvent/HandlePublish) for broadcasts that have no single target.","Align proto/AgentId mapping helpers between sender and receiver versions."],"exampleFix":"// before\nvar req = new RpcRequest { Payload = payload, RequestId = rid }; // no Target\n\n// after\nvar req = new RpcRequest\n{\n    Target = recipient.ToProtobuf(),\n    Payload = payload,\n    RequestId = rid,\n};","handlingStrategy":"validation","validationCode":"if (request?.Target is null)\n{\n    // sender bug: set Target = recipient.ToProtobuf() before dispatch\n}","typeGuard":"static bool HasTarget(RpcRequest? r) => r?.Target is not null;","tryCatchPattern":null,"preventionTips":["Always populate Target from the recipient AgentId when constructing RpcRequest.","Use publish (CloudEvent) for messages with no single destination."],"tags":["grpc","wire-protocol","routing","validation"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}