microsoft/semantic-kernel · error · KernelException

The target for the edge is not a function target.

Error message

The target for the edge is not a function target.

What it means

EnqueueExternalMessagesAsync processes external KernelProcessEvents sent to the process. For each edge associated with an external event, it requires edge.OutputTarget to be a KernelProcessFunctionTarget so it can resolve the destination step and function. The Dapr runtime at this call site does not handle other KernelProcessTarget subtypes (KernelProcessStateTarget, KernelProcessEmitTarget, KernelProcessAgentInvokeTarget).

Source

Thrown at dotnet/src/Experimental/Process.Runtime.Dapr/Actors/ProcessActor.cs:382

    /// <summary>
    /// Processes external events that have been sent to the process, translates them to <see cref="ProcessMessage"/>s, and enqueues
    /// them to the provided message channel so that they can be processed in the next superstep.
    /// </summary>
    private async Task EnqueueExternalMessagesAsync()
    {
        IExternalEventBuffer externalEventQueue = this.ProxyFactory.CreateActorProxy<IExternalEventBuffer>(new ActorId(this.Id.GetId()), nameof(ExternalEventBufferActor));
        IList<string> dequeuedEvents = await externalEventQueue.DequeueAllAsync().ConfigureAwait(false);
        IList<KernelProcessEvent> externalEvents = dequeuedEvents.ToKernelProcessEvents();

        foreach (KernelProcessEvent externalEvent in externalEvents)
        {
            if (this._outputEdges!.TryGetValue(externalEvent.Id!, out List<KernelProcessEdge>? edges) && edges is not null)
            {
                foreach (KernelProcessEdge edge in edges)
                {
                    if (edge.OutputTarget is not KernelProcessFunctionTarget functionTarget)
                    {
                        throw new KernelException("The target for the edge is not a function target.").Log(this._logger);
                    }

                    ProcessMessage message = ProcessMessageFactory.CreateFromEdge(edge, externalEvent.Id, externalEvent.Data);
                    var scopedMessageBufferId = this.ScopedActorId(new ActorId(functionTarget.StepId));
                    var messageQueue = this.ProxyFactory.CreateActorProxy<IMessageBuffer>(scopedMessageBufferId, nameof(MessageBufferActor));
                    await messageQueue.EnqueueAsync(message.ToJson()).ConfigureAwait(false);
                }
            }
        }
    }

    /// <summary>
    /// Check for the presence of an global-error event and any edges defined for processing it.
    /// When both exist, the error event is processed and sent to the appropriate targets.
    /// </summary>
    private async Task HandleGlobalErrorMessageAsync()
    {
        var errorEventQueue = this.ProxyFactory.CreateActorProxy<IEventBuffer>(ProcessActor.GetScopedGlobalErrorEventBufferId(this.Id.GetId()), nameof(EventBufferActor));

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure that all edges reachable from external events have OutputTarget of type KernelProcessFunctionTarget.
  2. If using state-update or agent-invoke targets, restrict them to edges that are only traversed by internal step-to-step messaging, not by the external-event entry path.
  3. Upgrade the Process.Runtime.Dapr package to a version that supports the additional target types if one is available.
Defensive patterns

Strategy: validation

Validate before calling

// Before building the process, validate that external-event edges only use function targets:
foreach (var edge in processBuilder.Build().Edges)
{
    if (edge.Value.Any(e => e.OutputTarget is not KernelProcessFunctionTarget))
    {
        throw new InvalidOperationException($"Edge for event {edge.Key} has a non-function target, unsupported by Dapr external-event routing.");
    }
}

Type guard

static bool IsFunctionTarget(KernelProcessEdge edge) => edge.OutputTarget is KernelProcessFunctionTarget;

Try / catch

try
{
    await process.StartAsync(keepAlive: true);
}
catch (KernelException ex) when (ex.Message.Contains("not a function target"))
{
    logger.LogError("An external event edge targets a non-function target type. The Dapr runtime only supports KernelProcessFunctionTarget for external events.");
}

Prevention

When it happens

Trigger: An external event is sent to the process whose output edge targets a non-function target type. This occurs when the process graph was built with state-update targets, emit targets, or agent-invocation targets on edges that the external-event path traverses.

Common situations: Using newer Semantic Kernel process features (state targets, agent invoke targets) with the Dapr runtime, which only fully supports KernelProcessFunctionTarget for external event routing. Also occurs from a corrupted or hand-crafted process graph where OutputTarget is set to an unexpected subtype.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/6b51f87c2be43ea5. Report an issue: GitHub.