{"record":{"id":"eccf8f3901f36122","repo":"microsoft/semantic-kernel","slug":"an-orchestration-is-referencing-a-node-with-id-l","errorCode":null,"errorMessage":"An orchestration is referencing a node with Id `{listenCondition.From}` that does not exist.","messagePattern":"An orchestration is referencing a node with Id `(.+?)` that does not exist\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.Core/Workflow/WorkflowBuilder.cs","lineNumber":278,"sourceCode":"                // Handle AllOf condition\n                edgeBuilder = processBuilder.ListenFor().AllOf(listenCondition.AllOf.Select(c => GetSourceBuilder(c)).ToList());\n            }\n            else if (!string.IsNullOrWhiteSpace(listenCondition.Event) && !string.IsNullOrWhiteSpace(listenCondition.From))\n            {\n                // Find the source of the edge, it could either be a step, or an input event.\n                if (this._stepBuilders.TryGetValue(listenCondition.From, out ProcessStepBuilder? sourceStepBuilder))\n                {\n                    // The source is a step.\n                    edgeBuilder = sourceStepBuilder.OnEvent(listenCondition.Event);\n                }\n                else if (listenCondition.From.Equals(\"_workflow_\", StringComparison.OrdinalIgnoreCase) && this._inputEvents.ContainsKey(listenCondition.Event))\n                {\n                    // The source is an input event.\n                    edgeBuilder = processBuilder.OnInputEvent(listenCondition.Event);\n                }\n                else\n                {\n                    throw new ArgumentException($\"An orchestration is referencing a node with Id `{listenCondition.From}` that does not exist.\");\n                }\n            }\n            else\n            {\n                throw new ArgumentException(\"A complete listen_for condition is required for orchestration steps.\");\n            }\n\n            // Now that we have a validated edge source, we can add the then actions\n            foreach (var action in thenActions)\n            {\n                if (action is null || string.IsNullOrWhiteSpace(action.Node))\n                {\n                    throw new ArgumentException(\"A complete then action is required for orchestration steps.\");\n                }\n\n                if (!this._stepBuilders.TryGetValue(action.Node, out ProcessStepBuilder? destinationStepBuilder))\n                {\n                    if (action.Node.Equals(\"End\", StringComparison.OrdinalIgnoreCase))","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.Core/Workflow/WorkflowBuilder.cs#L260-L296","documentation":"Thrown by WorkflowBuilder when constructing an orchestration edge whose `listen_for.from` Id does not match any registered step and is not the literal sentinel `\"_workflow_\"` paired with a known input event. The builder resolves the edge source from an internal `_stepBuilders` map keyed by step Id; an unresolved key means the workflow's orchestration references a node that was never added (or was renamed). It is an ArgumentException raised during `AddOrchestrationStepAsync` while translating a declarative workflow into a process graph.","triggerScenarios":"Call the workflow builder with an orchestration step whose `listen_for.from` value (a) is not present in the `steps` collection, (b) is `\"_workflow_\"` but whose `event` is not in `_inputEvents`, or (c) contains a typo/different casing than the step's registered Id. Renaming a step without updating its orchestration `from` also triggers it.","commonSituations":"Hand-authoring a YAML/declarative workflow and mistyping a node id; refactoring a step and forgetting to update downstream `listen_for` references; using an input event name that was never declared via `process.OnInputEvent(...)`; copy-pasting orchestration blocks between workflows with divergent node ids.","solutions":["Open the workflow definition and confirm every `listen_for.from` value exactly matches a step Id declared under `steps` (case-sensitive, no surrounding whitespace).","If the source is a process-level input event, set `from` to `\"_workflow_\"` and ensure the event name was registered with `OnInputEvent`.","Re-run after any step rename and propagate the new Id to all orchestration `listen_for.from` and `then.node` references.","Add a pre-build validation pass that collects all step Ids and asserts each orchestration `from`/`node` resolves before calling the builder."],"exampleFix":"// before\nlisten_for:\n  from: MyStep\n  event: Started\n// after (fixed typo against actual step id 'MyStepA')\nlisten_for:\n  from: MyStepA\n  event: Started","handlingStrategy":"validation","validationCode":"// Before building, confirm every orchestration 'from' resolves to a step or is the input-event sentinel.\nvar stepIds = new HashSet<string>(workflow.Nodes.Select(n => n.Id), StringComparer.Ordinal);\nvar inputEvents = new HashSet<string>(declaredInputEvents, StringComparer.Ordinal);\nforeach (var step in workflow.Orchestration)\n{\n    var lc = step.ListenFor;\n    if (lc == null) continue;\n    var sources = lc.AllOf?.Select(a => a.From).Append(lc.From).Where(f => !string.IsNullOrWhiteSpace(f))\n                  ?? new[] { lc.From };\n    foreach (var from in sources)\n    {\n        if (!stepIds.Contains(from)\n            && !(from.Equals(\"_workflow_\", StringComparison.OrdinalIgnoreCase) && inputEvents.Contains(lc.Event)))\n        {\n            throw new InvalidOperationException($\"listen_for.from '{from}' does not match any step or declared input event.\");\n        }\n    }\n}","typeGuard":"bool IsValidListenFrom(Workflow wf, string from, string evt) =>\n    wf.Nodes.Any(n => string.Equals(n.Id, from, StringComparison.Ordinal))\n    || (from.Equals(\"_workflow_\", StringComparison.OrdinalIgnoreCase)\n        && wf.InputEvents.Contains(evt, StringComparer.Ordinal));","tryCatchPattern":"try { await builder.BuildAsync(); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"does not exist\"))\n{\n    _logger.LogError(ex, \"Workflow orchestration references an unknown node; aborting build.\");\n    throw;\n}","preventionTips":["Keep a single source of truth for step ids and reference them by constant/enum, not string literals.","Run a structural validator over the workflow before invoking the builder.","After renaming a step, grep the workflow definition for all listen_for.from and then.node references."],"tags":["workflow","process-framework","validation","orchestration","declarative"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}