microsoft/semantic-kernel · error · InvalidOperationException

A target and Source must be specified before building the ed

Error message

A target and Source must be specified before building the edge.

What it means

Thrown by ProcessStepEdgeBuilder.Build when an edge is being materialized but either the Target was never set or the Source step has no Id. Build requires both a non-null Target and a non-null Source.Id to construct a KernelProcessEdge.

Source

Thrown at dotnet/src/Experimental/Process.Core/ProcessStepEdgeBuilder.cs:69

        Verify.NotNull(source, nameof(source));
        Verify.NotNullOrWhiteSpace(eventId, nameof(eventId));

        this.Source = source;
        this.EventData = new() { EventId = eventId, EventName = eventName };
        this.EdgeGroupBuilder = edgeGroupBuilder;
        this.Condition = condition;
    }

    /// <summary>
    /// Builds the edge.
    /// </summary>
    internal KernelProcessEdge Build(ProcessBuilder? processBuilder = null)
    {
        Verify.NotNull(this.Source?.Id);

        if (this.Target is null || this.Source?.Id is null)
        {
            throw new InvalidOperationException("A target and Source must be specified before building the edge.");
        }

        if (this.Target is ProcessFunctionTargetBuilder functionTargetBuilder)
        {
            if (this.EdgeGroupBuilder is not null && this.Target is ProcessStepTargetBuilder stepTargetBuilder)
            {
                var messageSources = this.EdgeGroupBuilder.MessageSources.Select(e => new KernelProcessMessageSource(e.MessageType, e.Source.Id)).ToList();
                var edgeGroup = new KernelProcessEdgeGroup(this.EdgeGroupBuilder.GroupId, messageSources, stepTargetBuilder.InputMapping);
                functionTargetBuilder.Step.RegisterGroupInputMapping(edgeGroup);
            }
        }

        return new KernelProcessEdge(this.Source.Id, this.Target.Build(processBuilder), groupId: this.EdgeGroupBuilder?.GroupId, this.Condition, this.VariableUpdate);
    }

    /// <summary>
    /// Signals that the output of the source step should be sent to the specified target when the associated event fires.
    /// </summary>

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Complete the edge definition by calling SendEventTo (or an equivalent target setter) before Build runs.
  2. Ensure the source step has a non-null Id by naming/registering it in the ProcessBuilder before building edges.
  3. If you instantiate ProcessStepEdgeBuilder directly, set both Source.Id and Target before invoking Build.
  4. Audit the fluent chain to confirm no .OnEvent(...).SendEventTo(...) branch was left without a terminal SendEventTo.

Example fix

// before: edge has no target
step.OnEvent("Done")
//   .SendEventTo(...) missing

// after: terminate with a target
step.OnEvent("Done")
   .SendEventTo(otherStep);
Defensive patterns

Strategy: validation

Validate before calling

if (edge.Target is null || string.IsNullOrEmpty(edge.Source?.Id))
    throw new InvalidOperationException("Edge is incomplete; set Target and Source.Id first.");

Type guard

static bool IsEdgeComplete(ProcessStepEdgeBuilder e) => e.Target is not null && !string.IsNullOrEmpty(e.Source?.Id);

Try / catch

try { var kernelEdge = edgeBuilder.Build(processBuilder); }
catch (InvalidOperationException ex) when (ex.Message.Contains("target and Source"))
{ /* ensure SendEventTo was called and Source.Id is set */ }

Prevention

When it happens

Trigger: Calling Build() on an edge builder whose SendEventTo/ConfigureTarget was never invoked, or whose source ProcessStepBuilder has a null Id (not yet named/registered). Also reachable if framework code calls Build on a freshly created edge before linking.

Common situations: Building a process programmatically and forgetting to chain .SendEventTo(...); creating an edge manually for testing without assigning a target; or a step whose Id assignment was skipped.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/829e10d6a20d7cc6. Report an issue: GitHub.