microsoft/semantic-kernel · error · InvalidOperationException
An output target has already been set.
Error message
An output target has already been set.
What it means
Thrown by ProcessEdgeBuilder.SendEventTo when the Target property is already set. Each ProcessEdgeBuilder represents a single edge from a source event to exactly one target; calling SendEventTo twice on the same edge builder attempts to assign a second target, which is not permitted.
Source
Thrown at dotnet/src/Experimental/Process.Core/ProcessEdgeBuilder.cs:42
this.Source = source;
}
/// <summary>
/// Sends the output of the source step to the specified target when the associated event fires.
/// </summary>
public ProcessEdgeBuilder SendEventTo(ProcessFunctionTargetBuilder target)
{
return this.SendEventTo(target as ProcessTargetBuilder);
}
/// <summary>
/// Sends the output of the source step to the specified target when the associated event fires.
/// </summary>
public new ProcessEdgeBuilder SendEventTo(ProcessTargetBuilder target)
{
if (this.Target is not null)
{
throw new InvalidOperationException("An output target has already been set.");
}
this.Target = target;
ProcessStepEdgeBuilder edgeBuilder = new(this.Source, this.EventData.EventId, this.EventData.EventId) { Target = this.Target };
this.Source.LinkTo(this.EventData.EventId, edgeBuilder);
return new ProcessEdgeBuilder(this.Source, this.EventData.EventId);
}
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Chain SendEventTo calls correctly by using the returned ProcessEdgeBuilder, not re-calling on the same instance.
- If you need to send the same event to multiple targets, use the OnInputEvent/ListenFor fluent API to create separate edges for each target.
- Avoid storing the ProcessEdgeBuilder in a variable and calling methods on it multiple times; prefer fluent chaining.
Example fix
// before — reusing the same builder variable
var edge = step.OnFunction("MyFunc");
edge.SendEventTo(targetA);
edge.SendEventTo(targetB); // throws: target already set
// after — chain from the return value
step.OnFunction("MyFunc")
.SendEventTo(targetA);
step.OnFunction("MyFunc")
.SendEventTo(targetB); // separate edge for each target Defensive patterns
Strategy: validation
Prevention
- Never call SendEventTo twice on the same ProcessEdgeBuilder instance — always chain from the return value.
- Use fluent chaining: step.OnFunction("Func").SendEventTo(target) rather than storing intermediate builders.
- To send the same event to multiple targets, create separate edges via separate OnFunction calls.
When it happens
Trigger: Chaining .SendEventTo(targetA).SendEventTo(targetB) on the same ProcessEdgeBuilder instance — the second SendEventTo call triggers this. The first SendEventTo returns a new ProcessEdgeBuilder, so this only happens if you reuse the original builder object rather than the returned one.
Common situations: Saving a ProcessEdgeBuilder reference in a variable and calling SendEventTo on it twice instead of chaining off the return value; misunderstanding the fluent builder pattern where SendEventTo returns a new builder; accidentally calling SendEventTo on a shared edge builder from multiple code paths.
Related errors
- Entry agent is not defined.
- Unable to transform output to {typeof(TOutput)}.
- Unable to transform result into {typeof(TOutput).Name}
- Invalid AgentId key: '{key}'. Must only contain ASCII charac
- Invalid AgentId type: '{type}'. Must be alphanumeric (a-z, 0
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/bfccca97cca3a56b.
Report an issue: GitHub.