microsoft/semantic-kernel · error · ArgumentException
The first message in chat history must have either the syste
Error message
The first message in chat history must have either the system or user role
What it means
Thrown by MistralClient.ValidateChatHistory when the first message in ChatHistory has a role other than 'system' or 'user'. The Mistral API expects conversations to begin with a user or system message; starting with an assistant or tool message is invalid. This is enforced client-side as an ArgumentException.
Source
Thrown at dotnet/src/Connectors/Connectors.MistralAI/Client/MistralClient.cs:675
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)
{
Stream = stream,
Messages = chatHistory.SelectMany(chatMessage => this.ToMistralChatMessages(chatMessage, executionSettings?.ToolCallBehavior)).ToList(),
Temperature = executionSettings.Temperature,
TopP = executionSettings.TopP,View on GitHub (pinned to c028a0c7dc)
Solutions
- Insert a user or system message as the first element of ChatHistory.
- If seeding context, use history.AddSystemMessage(...) or history.AddUserMessage(...) before any assistant/tool messages.
- Validate and reorder loaded history: ensure messages[0].Role is user or system before calling the API.
Example fix
// before
var history = new ChatHistory();
history.AddAssistantMessage("Sure, I can help.");
// after
var history = new ChatHistory();
history.AddSystemMessage("You are a helpful assistant.");
history.AddAssistantMessage("Sure, I can help."); Defensive patterns
Strategy: validation
Validate before calling
if (chatHistory.Count > 0)
{
var firstRole = chatHistory[0].Role.ToString();
if (firstRole is not "system" and not "user")
throw new InvalidOperationException("First message must be system or user role.");
} Type guard
static bool HasValidFirstRole(ChatHistory history) =>
history.Count == 0 ||
history[0].Role.ToString() is "system" or "user"; Prevention
- Always add system or user messages first when building history.
- When loading persisted history, validate and reorder before sending.
- Use a builder pattern that enforces role ordering.
When it happens
Trigger: Building a ChatHistory whose first Add* call is history.AddAssistantMessage(...) or history.AddMessage(AuthorRole.Tool, ...); restoring a persisted conversation and accidentally ordering an assistant message first.
Common situations: Loading chat history from a database where the ordering got corrupted; replaying a tool-call sequence without a preceding user turn; multi-turn apps that prepend a previous assistant reply as context.
Related errors
- Chat history must contain at least one message
- Chat history can't contain only system messages.
- A function name can contain only ASCII letters, digits, dash
- System messages cannot be added to the chat history.
- Tool message found without a preceding message.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/5d65ee16c20e1ad2.
Report an issue: GitHub.