{"record":{"id":"60e8013015e66396","repo":"microsoft/semantic-kernel","slug":"message-messagekey-is-not-expected-for-edge-grou","errorCode":null,"errorMessage":"Message {messageKey} is not expected for edge group {this._edgeGroup.GroupId}.","messagePattern":"Message (.+?) is not expected for edge group (.+?)\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.LocalRuntime/LocalEdgeGroupProcessor.cs","lineNumber":28,"sourceCode":"    private readonly KernelProcessEdgeGroup _edgeGroup;\n    private readonly Dictionary<string, object?> _messageData = [];\n    private HashSet<string> _requiredMessages = [];\n    private HashSet<string> _absentMessages = [];\n\n    public LocalEdgeGroupProcessor(KernelProcessEdgeGroup edgeGroup)\n    {\n        Verify.NotNull(edgeGroup, nameof(edgeGroup));\n        this._edgeGroup = edgeGroup;\n\n        this.InitializeEventTracking();\n    }\n\n    public bool TryGetResult(ProcessMessage message, out Dictionary<string, object?>? result)\n    {\n        string messageKey = this.GetKeyForMessageSource(message);\n        if (!this._requiredMessages.Contains(messageKey))\n        {\n            throw new KernelException($\"Message {messageKey} is not expected for edge group {this._edgeGroup.GroupId}.\");\n        }\n\n        this._messageData[messageKey] = (message.TargetEventData as KernelProcessEventData)!.ToObject();\n\n        this._absentMessages.Remove(messageKey);\n        if (this._absentMessages.Count == 0)\n        {\n            // We have received all required events so forward them to the target\n            result = (Dictionary<string, object?>?)this._edgeGroup.InputMapping(this._messageData);\n\n            // TODO: Reset state according to configured logic i.e. reset after first message or after all messages are received.\n            this.InitializeEventTracking();\n\n            return true;\n        }\n\n        result = null;\n        return false;","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.LocalRuntime/LocalEdgeGroupProcessor.cs#L10-L46","documentation":"Thrown by LocalEdgeGroupProcessor.TryGetResult when an incoming message's key (composed as '{SourceId}.{SourceEventId}') is not present in the edge group's required message sources. The edge group collects messages from multiple source steps and only fires when all declared sources have delivered their messages; this error means a message arrived from a source/event combination the group was not configured to accept.","triggerScenarios":"A ProcessMessage is routed to a step whose KernelProcessEdgeGroup is registered, but the message's SourceId + SourceEventId pair does not match any KernelProcessMessageSource declared in the group's MessageSources list. This occurs when an edge connects a source step to a grouped target but the source's event id or step id does not align with what the group expects.","commonSituations":"Renaming a step or event id without updating the edge group's MessageSources; wiring an edge to a grouped input using the wrong event id; version changes where the emitted event id changed but the group definition was not migrated; a message from an unrelated source step accidentally sharing the same GroupId.","solutions":["Compare the message's SourceId and SourceEventId against each entry in the edge group's MessageSources (which use SourceStepId.MessageType) and correct whichever side is wrong.","Verify that the edge defining the source-to-group routing uses the exact event id the source step emits.","Check that the GroupId on the outgoing edges matches the group registered on the target step's IncomingEdgeGroups.","If you renamed a step or event, update all KernelProcessEdgeGroup.MessageSources entries that reference the old names."],"exampleFix":"// before - MessageSources references the wrong event id\ngroup.AddEdgeSource(new KernelProcessMessageSource { SourceStepId = \"MyStep\", MessageType = \"ProcessEventA\" });\n// after - corrected to match what MyStep actually emits\ngroup.AddEdgeSource(new KernelProcessMessageSource { SourceStepId = \"MyStep\", MessageType = \"ProcessEventB\" });","handlingStrategy":"validation","validationCode":"// Validate that each source step/event feeding an edge group is declared in the group's MessageSources\nforeach (var group in step.IncomingEdgeGroups.Values)\n{\n    foreach (var source in group.MessageSources)\n    {\n        var expectedKey = $\"{source.SourceStepId}.{source.MessageType}\";\n        // Ensure an edge exists from source.SourceStepId emitting source.MessageType into this step with this group\n        var matchingEdge = process.Edges\n            .SelectMany(kvp => kvp.Value)\n            .Where(e => e.Source.EventId == source.MessageType && e.OutputTarget.StepId == step.State.Id)\n            .Any();\n        if (!matchingEdge) { /* log or throw configuration error */ }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After building the process, iterate all edge groups and verify every MessageSource has a corresponding edge.","Use a process-builder validation pass before StartAsync to catch source/event mismatches early.","Keep step ids and event ids stable across refactors; update edge group definitions when renaming."],"tags":["process-framework","edge-group","message-routing","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}