{"record":{"id":"6b51f87c2be43ea5","repo":"microsoft/semantic-kernel","slug":"the-target-for-the-edge-is-not-a-function-target","errorCode":null,"errorMessage":"The target for the edge is not a function target.","messagePattern":"The target for the edge is not a function target\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.Runtime.Dapr/Actors/ProcessActor.cs","lineNumber":382,"sourceCode":"    /// <summary>\n    /// Processes external events that have been sent to the process, translates them to <see cref=\"ProcessMessage\"/>s, and enqueues\n    /// them to the provided message channel so that they can be processed in the next superstep.\n    /// </summary>\n    private async Task EnqueueExternalMessagesAsync()\n    {\n        IExternalEventBuffer externalEventQueue = this.ProxyFactory.CreateActorProxy<IExternalEventBuffer>(new ActorId(this.Id.GetId()), nameof(ExternalEventBufferActor));\n        IList<string> dequeuedEvents = await externalEventQueue.DequeueAllAsync().ConfigureAwait(false);\n        IList<KernelProcessEvent> externalEvents = dequeuedEvents.ToKernelProcessEvents();\n\n        foreach (KernelProcessEvent externalEvent in externalEvents)\n        {\n            if (this._outputEdges!.TryGetValue(externalEvent.Id!, out List<KernelProcessEdge>? edges) && edges is not null)\n            {\n                foreach (KernelProcessEdge edge in edges)\n                {\n                    if (edge.OutputTarget is not KernelProcessFunctionTarget functionTarget)\n                    {\n                        throw new KernelException(\"The target for the edge is not a function target.\").Log(this._logger);\n                    }\n\n                    ProcessMessage message = ProcessMessageFactory.CreateFromEdge(edge, externalEvent.Id, externalEvent.Data);\n                    var scopedMessageBufferId = this.ScopedActorId(new ActorId(functionTarget.StepId));\n                    var messageQueue = this.ProxyFactory.CreateActorProxy<IMessageBuffer>(scopedMessageBufferId, nameof(MessageBufferActor));\n                    await messageQueue.EnqueueAsync(message.ToJson()).ConfigureAwait(false);\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Check for the presence of an global-error event and any edges defined for processing it.\n    /// When both exist, the error event is processed and sent to the appropriate targets.\n    /// </summary>\n    private async Task HandleGlobalErrorMessageAsync()\n    {\n        var errorEventQueue = this.ProxyFactory.CreateActorProxy<IEventBuffer>(ProcessActor.GetScopedGlobalErrorEventBufferId(this.Id.GetId()), nameof(EventBufferActor));","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.Runtime.Dapr/Actors/ProcessActor.cs#L364-L400","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure that all edges reachable from external events have OutputTarget of type KernelProcessFunctionTarget.","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.","Upgrade the Process.Runtime.Dapr package to a version that supports the additional target types if one is available."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before building the process, validate that external-event edges only use function targets:\nforeach (var edge in processBuilder.Build().Edges)\n{\n    if (edge.Value.Any(e => e.OutputTarget is not KernelProcessFunctionTarget))\n    {\n        throw new InvalidOperationException($\"Edge for event {edge.Key} has a non-function target, unsupported by Dapr external-event routing.\");\n    }\n}","typeGuard":"static bool IsFunctionTarget(KernelProcessEdge edge) => edge.OutputTarget is KernelProcessFunctionTarget;","tryCatchPattern":"try\n{\n    await process.StartAsync(keepAlive: true);\n}\ncatch (KernelException ex) when (ex.Message.Contains(\"not a function target\"))\n{\n    logger.LogError(\"An external event edge targets a non-function target type. The Dapr runtime only supports KernelProcessFunctionTarget for external events.\");\n}","preventionTips":["Use only KernelProcessFunctionTarget on edges reachable from external events in the Dapr runtime.","Avoid state-update, emit, or agent-invoke targets on external-event entry edges.","Upgrade the Process.Runtime.Dapr package when support for additional target types is added."],"tags":["dapr","process-runtime","edge-target","external-events","semantic-kernel"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}