microsoft/semantic-kernel · error · InvalidOperationException

Source step cannot be null.

Error message

Source step cannot be null.

What it means

Thrown by ListenForTargetBuilder.SendEventTo_Internal when iterating over _messageSources and finding a MessageSourceBuilder whose Source property is null. The ListenFor pattern requires every message source to reference a concrete source step so it can wire up an OnEvent edge.

Source

Thrown at dotnet/src/Experimental/Process.Core/ListenForTargetBuilder.cs:87

    internal ListenForTargetBuilder EmitEvent(string eventName, Dictionary<string, string>? payload = null)
    {
        Verify.NotNullOrWhiteSpace(eventName, nameof(eventName));
        this.SendEventTo_Internal(new ProcessEmitTargetBuilder(eventName, payload));
        return new ListenForTargetBuilder(this._messageSources, this._processBuilder, this.EdgeGroupBuilder);
    }

    /// <summary>
    /// Sends the event to the specified target.
    /// </summary>
    /// <param name="target">The target to send the event to.</param>
    /// <returns>A new instance of <see cref="ListenForTargetBuilder"/>.</returns>
    internal override ProcessStepEdgeBuilder SendEventTo_Internal(ProcessTargetBuilder target)
    {
        foreach (var messageSource in this._messageSources)
        {
            if (messageSource.Source == null)
            {
                throw new InvalidOperationException("Source step cannot be null.");
            }

            // Link all the source steps to the event listener
            var onEventBuilder = messageSource.Source.OnEvent(messageSource.MessageType);
            onEventBuilder.EdgeGroupBuilder = this.EdgeGroupBuilder;

            if (messageSource.Condition != null)
            {
                onEventBuilder.Condition = messageSource.Condition;
            }
            onEventBuilder.SendEventTo(target);
        }

        return new ListenForTargetBuilder(this._messageSources, this._processBuilder, edgeGroup: this.EdgeGroupBuilder);
    }

    /// <summary>
    /// Signals that the process should be stopped.

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure every source step passed into ListenFor/Message is a fully constructed ProcessStepBuilder with a non-null reference before calling SendEventTo.
  2. Debug the _messageSources list at the point of the call to identify which MessageSourceBuilder has a null Source and fix or remove it.
  3. Avoid creating MessageSourceBuilder instances directly; use the public ListenFor API which validates source steps.
Defensive patterns

Strategy: validation

Validate before calling

// Validate message sources before calling SendEventTo on a ListenForTargetBuilder.
// Ensure all MessageSourceBuilder instances have non-null Source.
public bool ValidateSources(List<MessageSourceBuilder> sources)
{
    return sources.All(s => s.Source is not null);
}

Prevention

When it happens

Trigger: A MessageSourceBuilder in the _messageSources list has a null Source, meaning the originating step was never set or was lost during builder cloning/copying. This occurs when ListenFor().Message(...) is called with a source step that was not yet built or was set to null.

Common situations: Using the internal ListenForBuilder API to define complex multi-source listeners where one source step is still null (not yet resolved). Copying or reusing a ListenForTargetBuilder whose message sources include a dangling reference. Building a process programmatically where a step is added to a listener before the step itself is fully constructed.

Related errors


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