{"record":{"id":"e7df08688576d0b1","repo":"microsoft/semantic-kernel","slug":"internal-process-error-the-target-event-id-must-b","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":"error","filePath":"dotnet/src/Experimental/Process.LocalRuntime/LocalProcess.cs","lineNumber":184,"sourceCode":"    /// <summary>\n    /// Gets the process information.\n    /// </summary>\n    /// <returns>An instance of <see cref=\"KernelProcess\"/></returns>\n    internal Task<KernelProcess> GetProcessInfoAsync() => this.ToKernelProcessAsync();\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    /// <returns>A <see cref=\"Task\"/></returns>\n    /// <exception cref=\"KernelException\"></exception>\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            // 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, Visibility = KernelProcessEventVisibility.Internal };\n\n            // Run the nested process completely within a single superstep.\n            await this.RunOnceAsync(nestedEvent, this._kernel).ConfigureAwait(false);\n        }\n    }\n\n    #region Private Methods\n\n    /// <summary>\n    /// Loads the process and initializes the steps. Once this is complete the process can be started.","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.LocalRuntime/LocalProcess.cs#L166-L202","documentation":"Thrown by LocalProcess.HandleMessageAsync when a ProcessMessage arrives with a null or whitespace TargetEventId. This code path executes only when a process runs as a nested step inside a parent process; the message must specify which event (and thus which output edge) to trigger inside the sub-process. A missing TargetEventId means the parent process's edge routing produced an incomplete message.","triggerScenarios":"A parent process contains a KernelProcess step, and an edge targeting that sub-process emits a ProcessMessage whose TargetEventId was never set. This can happen if ProcessMessageFactory.CreateFromEdge or custom message construction omits the target event id, or if the edge's OutputTarget lacks a target event id.","commonSituations":"Custom edge construction that manually creates ProcessMessage without setting TargetEventId; a bug or version mismatch in the framework's message factory; an edge target type that does not populate the event id (e.g., a state target or emit target mistakenly routed to a nested process).","solutions":["Ensure every edge that targets a KernelProcess (sub-process) step uses a KernelProcessFunctionTarget or equivalent that carries a valid TargetEventId.","If constructing ProcessMessage manually, always set TargetEventId to the event id the sub-process expects.","Check that the edge's source event id is non-empty and maps to an entry in the sub-process's Edges dictionary.","If this appears during a framework upgrade, verify ProcessMessageFactory.CreateFromEdge populates TargetEventId for your edge target type."],"exampleFix":"// before - manual message missing TargetEventId\nvar msg = new ProcessMessage { DestinationId = subprocessId, FunctionName = \"Start\" };\n// after - set TargetEventId\nvar msg = new ProcessMessage { DestinationId = subprocessId, TargetEventId = \"StartProcess\", FunctionName = \"Start\" };","handlingStrategy":"validation","validationCode":"// Before starting a process that contains sub-processes, verify all edges targeting sub-process steps carry a target event id\nforeach (var edgeList in parentProcess.Edges.Values)\n{\n    foreach (var edge in edgeList)\n    {\n        if (edge.OutputTarget is KernelProcessFunctionTarget ft && subProcessIds.Contains(ft.StepId))\n        {\n            if (string.IsNullOrWhiteSpace(ft.TargetEventId)) { /* configuration error */ }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct ProcessMessage manually for sub-process steps; always use ProcessMessageFactory.CreateFromEdge.","Ensure edges to sub-process steps specify a valid target event id.","Run the process in debug mode and verify TargetEventId is populated before HandleMessageAsync."],"tags":["process-framework","nested-process","message-routing","internal-error"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}