microsoft/semantic-kernel · error · ArgumentException
An orchestration is referencing a node with Id `{listenCondi
Error message
An orchestration is referencing a node with Id `{listenCondition.From}` that does not exist. What it means
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.
Source
Thrown at dotnet/src/Experimental/Process.Core/Workflow/WorkflowBuilder.cs:278
// Handle AllOf condition
edgeBuilder = processBuilder.ListenFor().AllOf(listenCondition.AllOf.Select(c => GetSourceBuilder(c)).ToList());
}
else if (!string.IsNullOrWhiteSpace(listenCondition.Event) && !string.IsNullOrWhiteSpace(listenCondition.From))
{
// Find the source of the edge, it could either be a step, or an input event.
if (this._stepBuilders.TryGetValue(listenCondition.From, out ProcessStepBuilder? sourceStepBuilder))
{
// The source is a step.
edgeBuilder = sourceStepBuilder.OnEvent(listenCondition.Event);
}
else if (listenCondition.From.Equals("_workflow_", StringComparison.OrdinalIgnoreCase) && this._inputEvents.ContainsKey(listenCondition.Event))
{
// The source is an input event.
edgeBuilder = processBuilder.OnInputEvent(listenCondition.Event);
}
else
{
throw new ArgumentException($"An orchestration is referencing a node with Id `{listenCondition.From}` that does not exist.");
}
}
else
{
throw new ArgumentException("A complete listen_for condition is required for orchestration steps.");
}
// Now that we have a validated edge source, we can add the then actions
foreach (var action in thenActions)
{
if (action is null || string.IsNullOrWhiteSpace(action.Node))
{
throw new ArgumentException("A complete then action is required for orchestration steps.");
}
if (!this._stepBuilders.TryGetValue(action.Node, out ProcessStepBuilder? destinationStepBuilder))
{
if (action.Node.Equals("End", StringComparison.OrdinalIgnoreCase))View on GitHub (pinned to c028a0c7dc)
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.
Example fix
// before listen_for: from: MyStep event: Started // after (fixed typo against actual step id 'MyStepA') listen_for: from: MyStepA event: Started
Defensive patterns
Strategy: validation
Validate before calling
// Before building, confirm every orchestration 'from' resolves to a step or is the input-event sentinel.
var stepIds = new HashSet<string>(workflow.Nodes.Select(n => n.Id), StringComparer.Ordinal);
var inputEvents = new HashSet<string>(declaredInputEvents, StringComparer.Ordinal);
foreach (var step in workflow.Orchestration)
{
var lc = step.ListenFor;
if (lc == null) continue;
var sources = lc.AllOf?.Select(a => a.From).Append(lc.From).Where(f => !string.IsNullOrWhiteSpace(f))
?? new[] { lc.From };
foreach (var from in sources)
{
if (!stepIds.Contains(from)
&& !(from.Equals("_workflow_", StringComparison.OrdinalIgnoreCase) && inputEvents.Contains(lc.Event)))
{
throw new InvalidOperationException($"listen_for.from '{from}' does not match any step or declared input event.");
}
}
} Type guard
bool IsValidListenFrom(Workflow wf, string from, string evt) =>
wf.Nodes.Any(n => string.Equals(n.Id, from, StringComparison.Ordinal))
|| (from.Equals("_workflow_", StringComparison.OrdinalIgnoreCase)
&& wf.InputEvents.Contains(evt, StringComparer.Ordinal)); Try / catch
try { await builder.BuildAsync(); }
catch (ArgumentException ex) when (ex.Message.Contains("does not exist"))
{
_logger.LogError(ex, "Workflow orchestration references an unknown node; aborting build.");
throw;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- An orchestration is referencing a node with Id `{action.Node
- A complete then action is required for orchestration steps.
- Only one `Default` handler is allowed in a group of event ha
- `Default` handlers must not have an eval expression.
- Only one `Always` handler is allowed in a group of event han
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/eccf8f3901f36122.
Report an issue: GitHub.