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

Thrown while routing an event along a KernelProcessEdge whose OutputTarget is not a KernelProcessFunctionTarget. The Dapr StepActor only knows how to deliver messages to function targets on downstream steps; any other edge target type is unsupported and stops event routing.

Source

Thrown at dotnet/src/Experimental/Process.Runtime.Dapr/Actors/StepActor.cs:466

                // Emit the event to the parent process
                IEventBuffer parentProcess = this.ProxyFactory.CreateActorProxy<IEventBuffer>(new ActorId(this.ParentProcessId), nameof(EventBufferActor));
                await parentProcess.EnqueueAsync(daprEvent.ToJson()).ConfigureAwait(false);
            }
        }

        if (this.EventProxyStepId != null)
        {
            IEventBuffer proxyBuffer = this.ProxyFactory.CreateActorProxy<IEventBuffer>(this.EventProxyStepId, nameof(EventBufferActor));
            await proxyBuffer.EnqueueAsync(daprEvent.ToJson()).ConfigureAwait(false);
        }

        // Get the edges for the event and queue up the messages to be sent to the next steps.
        bool foundEdge = false;
        foreach (KernelProcessEdge edge in this.GetEdgeForEvent(daprEvent.QualifiedId))
        {
            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, daprEvent.SourceId, daprEvent.Data);
            ActorId scopedStepId = this.ScopedActorId(new ActorId(functionTarget.StepId));
            IMessageBuffer targetStep = this.ProxyFactory.CreateActorProxy<IMessageBuffer>(scopedStepId, nameof(MessageBufferActor));
            await targetStep.EnqueueAsync(message.ToJson()).ConfigureAwait(false);
            foundEdge = true;
        }

        // Error event was raised with no edge to handle it, send it to the global error event buffer.
        if (!foundEdge && daprEvent.IsError && this.ParentProcessId != null)
        {
            IEventBuffer parentProcess1 = this.ProxyFactory.CreateActorProxy<IEventBuffer>(ProcessActor.GetScopedGlobalErrorEventBufferId(this.ParentProcessId), nameof(EventBufferActor));
            await parentProcess1.EnqueueAsync(daprEvent.ToJson()).ConfigureAwait(false);
        }
    }

    /// <summary>
    /// Scopes the Id of a step within the process to the process.

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Audit the process definition's edges and ensure every OutputTarget is a KernelProcessFunctionTarget before publishing to Dapr.
  2. Rebuild the process graph with the supported edge-target API; convert any map/proxy targets to the equivalent supported constructs.
  3. Upgrade Process.Runtime.Dapr to a version that supports the edge target subtype you are using, or downgrade the process definition to match.

Example fix

// before
edges.Add(new KernelProcessEdge(sourceId, new SomeOtherTarget(...)));
// after
edges.Add(new KernelProcessEdge(sourceId,
    new KernelProcessFunctionTarget(stepId: "MyStep", functionName: "Handle", parameterName: "input")));
Defensive patterns

Strategy: validation

Validate before calling

// Validate all edges before publishing the process
foreach (var edge in process.Edges.SelectMany(e => e.Value))
{
    if (edge.OutputTarget is not KernelProcessFunctionTarget)
    {
        throw new InvalidOperationException($"Edge target {edge.OutputTarget.GetType().Name} is unsupported by the Dapr runtime.");
    }
}

Type guard

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

Try / catch

try
{
    await stepActor.HandleEventAsync(daprEvent).ConfigureAwait(false);
}
catch (KernelException ex) when (ex.Message.Contains("not a function target"))
{
    _logger.LogError("Edge for event {Id} has an unsupported target type.", daprEvent.QualifiedId);
    throw;
}

Prevention

When it happens

Trigger: Raised in the event-handling path of StepActor when iterating GetEdgeForEvent for an incoming daprEvent and encountering an edge whose OutputTarget is a different subtype (e.g., a map/proxy target) rather than KernelProcessFunctionTarget.

Common situations: A process definition was built with edges pointing at non-function targets (maps, proxies, or custom edge targets), persisted, and then loaded by a Dapr runtime version that only supports function targets. Also arises from bugs in process graph construction or schema drift between definition and runtime.

Related errors


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