{"record":{"id":"0a641d9ed8a3a20c","repo":"microsoft/semantic-kernel","slug":"step-this-name-received-message-from-step-named","errorCode":null,"errorMessage":"Step {this.Name} received message from Step named '{message.SourceId}' with group Id '{message.GroupId}' that is not registered.","messagePattern":"Step (.+?) received message from Step named '(.+?)' with group Id '(.+?)' that is not registered\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.LocalRuntime/LocalStep.cs","lineNumber":196,"sourceCode":"        Verify.NotNull(message, nameof(message));\n\n        // Lazy one-time initialization of the step before processing a message\n        await this._initializeTask.Value.ConfigureAwait(false);\n\n        if (this._functions is null || this._inputs is null || this._initialInputs is null)\n        {\n            throw new KernelException(\"The step has not been initialized.\").Log(this._logger);\n        }\n\n        string messageLogParameters = string.Join(\", \", message.Values.Select(kvp => $\"{kvp.Key}: {kvp.Value}\"));\n        this._logger.LogDebug(\"Received message from '{SourceId}' targeting function '{FunctionName}' and parameters '{Parameters}'.\", message.SourceId, message.FunctionName, messageLogParameters);\n\n        if (!string.IsNullOrEmpty(message.GroupId))\n        {\n            this._logger.LogDebug(\"Step {StepName} received message from Step named '{SourceId}' with group Id '{GroupId}'.\", this.Name, message.SourceId, message.GroupId);\n            if (!this._edgeGroupProcessors.TryGetValue(message.GroupId, out LocalEdgeGroupProcessor? edgeGroupProcessor) || edgeGroupProcessor is null)\n            {\n                throw new KernelException($\"Step {this.Name} received message from Step named '{message.SourceId}' with group Id '{message.GroupId}' that is not registered.\").Log(this._logger);\n            }\n\n            if (!edgeGroupProcessor.TryGetResult(message, out Dictionary<string, object?>? result))\n            {\n                // The edge group processor has not received all required messages yet.\n                return;\n            }\n\n            // The edge group processor has received all required messages and has produced a result.\n            message = message with { Values = result ?? [] };\n        }\n\n        // Add the message values to the inputs for the function\n        this.AssignStepFunctionParameterValues(message);\n\n        // If we're still waiting for inputs on all of our functions then don't do anything.\n        List<string> invocableFunctions = this._inputs.Where(i => i.Value != null && i.Value.All(v => v.Value != null)).Select(i => i.Key).ToList();\n        var missingKeys = this._inputs.Where(i => i.Value is null || i.Value.Any(v => v.Value is null));","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.LocalRuntime/LocalStep.cs#L178-L214","documentation":"Thrown by LocalStep.HandleMessageAsync when a message has a non-empty GroupId that is not found in the step's _edgeGroupProcessors dictionary. Edge group processors are built from _stepInfo.IncomingEdgeGroups during construction; a GroupId on an incoming message that doesn't match any registered group means the source step's edge declared a group that the target step never registered.","triggerScenarios":"A source step's outgoing edge specifies a GroupId, and the message carries it to a target step, but the target step's IncomingEdgeGroups does not contain an entry for that GroupId. The lookup at line 194 fails.","commonSituations":"Adding a GroupId to an edge on the source side without declaring the corresponding KernelProcessEdgeGroup on the target step; renaming a GroupId on one side but not the other; using the wrong target step id so the message reaches a step that doesn't know about the group.","solutions":["Ensure every GroupId used on source-side edges has a matching KernelProcessEdgeGroup entry in the target step's IncomingEdgeGroups.","Verify the GroupId string matches exactly (case-sensitive) between the edge and the group definition.","Check that the edge's target step id is correct so messages reach the step that owns the group."],"exampleFix":"// before - edge declares group 'fanin1' but target step has no such group\nsource.OnEvent(\"evt\").To(target, \"func\", groupId: \"fanin1\");\n// after - register the group on the target step\ntarget.IncomingEdgeGroups[\"fanin1\"] = new KernelProcessEdgeGroup(\"fanin1\") { MessageSources = [...] };","handlingStrategy":"validation","validationCode":"// Validate that every GroupId on incoming edges is registered on the target step\nvar registeredGroups = step.IncomingEdgeGroups?.Keys.ToHashSet() ?? new HashSet<string>();\nforeach (var edgeList in process.Edges.Values)\n{\n    foreach (var edge in edgeList)\n    {\n        if (edge.OutputTarget is KernelProcessFunctionTarget ft && ft.StepId == step.State.Id && !string.IsNullOrEmpty(ft.GroupId))\n        {\n            if (!registeredGroups.Contains(ft.GroupId)) { /* configuration error */ }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register every KernelProcessEdgeGroup on the target step before defining edges that reference its GroupId.","Use constants for GroupId strings to avoid mismatches.","Run a pre-start validation pass that cross-references edge GroupIds with step IncomingEdgeGroups."],"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"}