{"record":{"id":"62c7a6342c77137d","repo":"microsoft/semantic-kernel","slug":"internal-process-error-the-target-event-id-must-b-62c7a6","errorCode":null,"errorMessage":"Internal Process Error: The target event id must be specified when sending a message to a step.","messagePattern":"Internal Process Error: The target event id must be specified when sending a message to a step\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"critical","filePath":"dotnet/src/Experimental/Process.Runtime.Dapr/Actors/ProcessActor.cs","lineNumber":201,"sourceCode":"\n    /// <summary>\n    /// The name of the step.\n    /// </summary>\n    protected override string Name => this._process?.State.Name ?? throw new KernelException(\"The Process must be initialized before accessing the Name property.\").Log(this._logger);\n\n    #endregion\n\n    /// <summary>\n    /// Handles a <see cref=\"ProcessMessage\"/> that has been sent to the process. This happens only in the case\n    /// of a process (this one) running as a step within another process (this one's parent). In this case the\n    /// entire sub-process should be executed within a single superstep.\n    /// </summary>\n    /// <param name=\"message\">The message to process.</param>\n    internal override async Task HandleMessageAsync(ProcessMessage message)\n    {\n        if (string.IsNullOrWhiteSpace(message.TargetEventId))\n        {\n            throw new KernelException(\"Internal Process Error: The target event id must be specified when sending a message to a step.\").Log(this._logger);\n        }\n\n        string eventId = message.TargetEventId!;\n        if (this._outputEdges!.TryGetValue(eventId, out List<KernelProcessEdge>? edges) && edges is not null)\n        {\n            foreach (var edge in edges)\n            {\n                // Create the external event that will be used to start the nested process. Since this event came\n                // from outside this processes, we set the visibility to internal so that it's not emitted back out again.\n                KernelProcessEvent nestedEvent = new() { Id = eventId, Data = message.TargetEventData };\n\n                // Run the nested process completely within a single superstep.\n                await this.RunOnceAsync(nestedEvent.ToJson()).ConfigureAwait(false);\n            }\n        }\n    }\n\n    internal static ActorId GetScopedGlobalErrorEventBufferId(string processId) => new($\"{ProcessConstants.GlobalErrorEventId}_{processId}\");","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.Runtime.Dapr/Actors/ProcessActor.cs#L183-L219","documentation":"ProcessActor.HandleMessageAsync is invoked only when this process runs as a step inside a parent process. It requires the incoming ProcessMessage.TargetEventId to be non-empty because that value is used to look up output edges and create the nested KernelProcessEvent that starts the sub-process. A null or whitespace TargetEventId means the routing infrastructure failed to identify the sub-process entry point.","triggerScenarios":"A ProcessMessage arrives at a ProcessActor (acting as a nested step) whose TargetEventId was never set. This happens when ProcessMessageFactory.CreateFromEdge processes an edge whose KernelProcessFunctionTarget.TargetEventId is null (ordinary step-to-step edge misrouted to a sub-process) or when the message was constructed manually without setting TargetEventId.","commonSituations":"A process is embedded as a step in a parent process but its input edge was not configured via WhereInputEventIs(eventId) on the ProcessBuilder, so the TargetEventId defaults to null. Also occurs with custom or manually-constructed ProcessMessage objects that omit the field.","solutions":["When embedding a sub-process in a parent, configure the edge targeting the sub-process using ProcessBuilder.WhereInputEventIs(eventId) so that the generated KernelProcessFunctionTarget carries a non-null TargetEventId.","If constructing ProcessMessage objects manually (e.g. in a custom step or test), ensure TargetEventId is set to the sub-process entry event id.","Audit the process graph edges to confirm that every edge targeting a DaprProcessInfo node has an associated TargetEventId in its function target."],"exampleFix":"// before — edge to sub-process without input event id\nbuilder.OnEvent(EventId).SendInputToProcess(subProcess);\n\n// after — specify the input event id\nbuilder.OnEvent(EventId).SendInputToProcess(subProcess.WhereInputEventIs(StartEventId));","handlingStrategy":"validation","validationCode":"// When building a process graph with a sub-process step, always specify the input event:\nbuilder.OnEvent(SomeEvent)\n    .SendInputToProcess(subProcessBuilder.WhereInputEventIs(SubProcessStartEvent));\n\n// This ensures KernelProcessFunctionTarget.TargetEventId is non-null for edges targeting sub-processes.","typeGuard":null,"tryCatchPattern":"try\n{\n    await processStep.HandleMessageAsync(message);\n}\ncatch (KernelException ex) when (ex.Message.Contains(\"target event id must be specified\"))\n{\n    logger.LogError(\"Message routed to sub-process without TargetEventId. Check edge configuration.\");\n}","preventionTips":["Always call WhereInputEventIs(eventId) when connecting an edge to a sub-process or map.","Never construct ProcessMessage objects manually for sub-process routing without setting TargetEventId.","Audit process graphs for edges targeting DaprProcessInfo steps and verify each has a TargetEventId."],"tags":["dapr","process-runtime","message-routing","sub-process","semantic-kernel"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}