microsoft/semantic-kernel · error · InvalidOperationException

requires a message to be invoked.

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.

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.

Appendix: 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)