microsoft/semantic-kernel · error · ArgumentException

Chat history must contain at least one message

Error message

Chat history must contain at least one message

What it means

This error is thrown by MistralClient.ValidateChatHistory when the ChatHistory passed to a chat completion request contains zero messages. The Mistral chat completion API requires at least one message, and Semantic Kernel enforces this client-side before constructing the HTTP request. It is an ArgumentException on the chatHistory parameter.

Source

Thrown at dotnet/src/Connectors/Connectors.MistralAI/Client/MistralClient.cs:670

                usage.CompletionTokens,
                usage.TotalTokens);
        }

        s_promptTokensCounter.Add(usage.PromptTokens.Value);
        s_completionTokensCounter.Add(usage.CompletionTokens.Value);
        s_totalTokensCounter.Add(usage.TotalTokens.Value);
    }

    /// <summary>
    /// Messages are required and the first prompt role should be user or system.
    /// </summary>
    private void ValidateChatHistory(ChatHistory chatHistory)
    {
        Verify.NotNull(chatHistory);

        if (chatHistory.Count == 0)
        {
            throw new ArgumentException("Chat history must contain at least one message", nameof(chatHistory));
        }
        var firstRole = chatHistory[0].Role.ToString();
        if (firstRole is not "system" and not "user")
        {
            throw new ArgumentException("The first message in chat history must have either the system or user role", nameof(chatHistory));
        }
    }

    private ChatCompletionRequest CreateChatCompletionRequest(string modelId, bool stream, ChatHistory chatHistory, MistralAIPromptExecutionSettings executionSettings, Kernel? kernel = null)
    {
        if (this._logger.IsEnabled(LogLevel.Trace))
        {
            this._logger.LogTrace("ChatHistory: {ChatHistory}, Settings: {Settings}",
                JsonSerializer.Serialize(chatHistory, JsonOptionsCache.ChatHistory),
                JsonSerializer.Serialize(executionSettings));
        }

        var request = new ChatCompletionRequest(modelId)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure at least one user or system message is added to ChatHistory before calling the completion API.
  2. Add a guard in your code: if (chatHistory.Count == 0) return or prompt the user for input first.
  3. Seed the history with a system prompt at initialization so it is never empty.

Example fix

// before
var history = new ChatHistory();
var result = await service.GetChatMessageContentAsync(history);

// after
var history = new ChatHistory();
history.AddUserMessage(userInput); // ensure non-empty
var result = await service.GetChatMessageContentAsync(history);
Defensive patterns

Strategy: validation

Validate before calling

if (chatHistory is null || chatHistory.Count == 0)
{
    throw new InvalidOperationException("Cannot send an empty chat history to Mistral.");
}

Type guard

static bool HasMessages(ChatHistory history) => history is not null && history.Count > 0;

Prevention

When it happens

Trigger: Calling GetChatMessageContentAsync or GetStreamingChatMessageContentsAsync on MistralChatCompletionService with an empty ChatHistory (new ChatHistory()). Also passing a history whose messages were all filtered/removed before the call.

Common situations: Application starts a conversation with an empty history before the user types anything; a chat buffer was cleared but the completion call still fired; orchestration code conditionally appends messages and skips the user turn on an early exit.

Related errors


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