microsoft/semantic-kernel · error · InvalidOperationException

{nameof(CopilotStudioAgent)} requires a message to be invoke

Error message

{nameof(CopilotStudioAgent)} requires a message to be invoked.

What it means

Thrown by CopilotStudioAgent.InvokeAsync when the messages collection is empty (after the null-coalescing to an empty list). The Copilot Studio agent requires at least one user message to formulate a question for the underlying AskQuestionAsync call. This is a precondition guard, not a service error.

Source

Thrown at dotnet/src/Agents/Copilot/CopilotStudioAgent.cs:52

    }

    /// <summary>
    /// CopilotStudioAgent does not support instructions like other agents.
    /// </summary>
    internal new string? Instructions => null;

    /// <inheritdoc/>
    public override async IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> InvokeAsync(
        ICollection<ChatMessageContent> messages,
        AgentThread? thread = null,
        AgentInvokeOptions? options = null,
        [EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        messages ??= [];

        if (messages.Count == 0)
        {
            throw new InvalidOperationException($"{nameof(CopilotStudioAgent)} requires a message to be invoked.");
        }

        // Create a thread if needed
        CopilotStudioAgentThread agentThread = await this.EnsureThreadExistsWithMessagesAsync(
            messages,
            thread,
            () => new CopilotStudioAgentThread(this.Client) { Logger = this.ActiveLoggerFactory.CreateLogger<CopilotStudioAgentThread>() },
            cancellationToken).ConfigureAwait(false);

        // Invoke the agent
        IAsyncEnumerable<ChatMessageContent> invokeResults = this.InvokeInternalAsync(messages, agentThread, cancellationToken);

        // Return the results to the caller in AgentResponseItems.
        await foreach (ChatMessageContent result in invokeResults.ConfigureAwait(false))
        {
            await this.NotifyThreadOfNewMessage(agentThread, result, cancellationToken).ConfigureAwait(false);

            if (options?.OnIntermediateMessage is not null)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure the messages collection passed to InvokeAsync contains at least one ChatMessageContent before calling.
  2. Guard at the call site: check messages.Count > 0 before invoking.
  3. If user input is optional in your flow, supply a default/prompt message.

Example fix

// before
var messages = new List<ChatMessageContent>(); // empty
await foreach (var r in agent.InvokeAsync(messages, thread)) { ... }

// after
if (messages.Count == 0)
    messages.Add(new ChatMessageContent(AuthorRole.User, userInput));
await foreach (var r in agent.InvokeAsync(messages, thread)) { ... }
Defensive patterns

Strategy: validation

Validate before calling

if (messages is null || messages.Count == 0)
    throw new ArgumentException("At least one message is required to invoke the Copilot agent.", nameof(messages));

Type guard

static bool HasMessages(ICollection<ChatMessageContent>? m) => m is { Count: > 0 };

Try / catch

try { await foreach (var r in agent.InvokeAsync(messages, thread, ct)) { ... } }
catch (InvalidOperationException ex) when (ex.Message.Contains("requires a message"))
{
    logger.LogError("InvokeAsync called with no messages. Provide at least one user message.");
    throw;
}

Prevention

When it happens

Trigger: Calling agent.InvokeAsync(messages: []) or agent.InvokeAsync(messages: null) with no messages in the collection. Also when a caller conditionally builds a message list that ends up empty.

Common situations: Passing an empty ChatHistory; a UI flow that allows submission of no input; conditional message construction that produced zero items; refactoring that removed the message-add step.

Related errors


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