microsoft/semantic-kernel · critical · KernelException
Internal Process Error: The target event id must be specifie
Error message
Internal Process Error: The target event id must be specified when sending a message to a step.
What it means
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.
Source
Thrown at dotnet/src/Experimental/Process.Runtime.Dapr/Actors/ProcessActor.cs:201
/// <summary>
/// The name of the step.
/// </summary>
protected override string Name => this._process?.State.Name ?? throw new KernelException("The Process must be initialized before accessing the Name property.").Log(this._logger);
#endregion
/// <summary>
/// Handles a <see cref="ProcessMessage"/> that has been sent to the process. This happens only in the case
/// of a process (this one) running as a step within another process (this one's parent). In this case the
/// entire sub-process should be executed within a single superstep.
/// </summary>
/// <param name="message">The message to process.</param>
internal override async Task HandleMessageAsync(ProcessMessage message)
{
if (string.IsNullOrWhiteSpace(message.TargetEventId))
{
throw new KernelException("Internal Process Error: The target event id must be specified when sending a message to a step.").Log(this._logger);
}
string eventId = message.TargetEventId!;
if (this._outputEdges!.TryGetValue(eventId, out List<KernelProcessEdge>? edges) && edges is not null)
{
foreach (var edge in edges)
{
// Create the external event that will be used to start the nested process. Since this event came
// from outside this processes, we set the visibility to internal so that it's not emitted back out again.
KernelProcessEvent nestedEvent = new() { Id = eventId, Data = message.TargetEventData };
// Run the nested process completely within a single superstep.
await this.RunOnceAsync(nestedEvent.ToJson()).ConfigureAwait(false);
}
}
}
internal static ActorId GetScopedGlobalErrorEventBufferId(string processId) => new($"{ProcessConstants.GlobalErrorEventId}_{processId}");View on GitHub (pinned to c028a0c7dc)
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.
Example fix
// before — edge to sub-process without input event id builder.OnEvent(EventId).SendInputToProcess(subProcess); // after — specify the input event id builder.OnEvent(EventId).SendInputToProcess(subProcess.WhereInputEventIs(StartEventId));
Defensive patterns
Strategy: validation
Validate before calling
// When building a process graph with a sub-process step, always specify the input event:
builder.OnEvent(SomeEvent)
.SendInputToProcess(subProcessBuilder.WhereInputEventIs(SubProcessStartEvent));
// This ensures KernelProcessFunctionTarget.TargetEventId is non-null for edges targeting sub-processes. Try / catch
try
{
await processStep.HandleMessageAsync(message);
}
catch (KernelException ex) when (ex.Message.Contains("target event id must be specified"))
{
logger.LogError("Message routed to sub-process without TargetEventId. Check edge configuration.");
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The Process must be initialized before accessing the Name pr
- The target for the edge is not a function target.
- The parent process Id must be set before scoping to the pare
- The step has not been initialized.
- The proxy step can only handle 1 parameter object
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/62c7a6342c77137d.
Report an issue: GitHub.