{"record":{"id":"5d65ee16c20e1ad2","repo":"microsoft/semantic-kernel","slug":"the-first-message-in-chat-history-must-have-either","errorCode":null,"errorMessage":"The first message in chat history must have either the system or user role","messagePattern":"The first message in chat history must have either the system or user role","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Connectors/Connectors.MistralAI/Client/MistralClient.cs","lineNumber":675,"sourceCode":"        s_completionTokensCounter.Add(usage.CompletionTokens.Value);\n        s_totalTokensCounter.Add(usage.TotalTokens.Value);\n    }\n\n    /// <summary>\n    /// Messages are required and the first prompt role should be user or system.\n    /// </summary>\n    private void ValidateChatHistory(ChatHistory chatHistory)\n    {\n        Verify.NotNull(chatHistory);\n\n        if (chatHistory.Count == 0)\n        {\n            throw new ArgumentException(\"Chat history must contain at least one message\", nameof(chatHistory));\n        }\n        var firstRole = chatHistory[0].Role.ToString();\n        if (firstRole is not \"system\" and not \"user\")\n        {\n            throw new ArgumentException(\"The first message in chat history must have either the system or user role\", nameof(chatHistory));\n        }\n    }\n\n    private ChatCompletionRequest CreateChatCompletionRequest(string modelId, bool stream, ChatHistory chatHistory, MistralAIPromptExecutionSettings executionSettings, Kernel? kernel = null)\n    {\n        if (this._logger.IsEnabled(LogLevel.Trace))\n        {\n            this._logger.LogTrace(\"ChatHistory: {ChatHistory}, Settings: {Settings}\",\n                JsonSerializer.Serialize(chatHistory, JsonOptionsCache.ChatHistory),\n                JsonSerializer.Serialize(executionSettings));\n        }\n\n        var request = new ChatCompletionRequest(modelId)\n        {\n            Stream = stream,\n            Messages = chatHistory.SelectMany(chatMessage => this.ToMistralChatMessages(chatMessage, executionSettings?.ToolCallBehavior)).ToList(),\n            Temperature = executionSettings.Temperature,\n            TopP = executionSettings.TopP,","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Connectors/Connectors.MistralAI/Client/MistralClient.cs#L657-L693","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar history = new ChatHistory();\nhistory.AddAssistantMessage(\"Sure, I can help.\");\n\n// after\nvar history = new ChatHistory();\nhistory.AddSystemMessage(\"You are a helpful assistant.\");\nhistory.AddAssistantMessage(\"Sure, I can help.\");","handlingStrategy":"validation","validationCode":"if (chatHistory.Count > 0)\n{\n    var firstRole = chatHistory[0].Role.ToString();\n    if (firstRole is not \"system\" and not \"user\")\n        throw new InvalidOperationException(\"First message must be system or user role.\");\n}","typeGuard":"static bool HasValidFirstRole(ChatHistory history) =>\n    history.Count == 0 ||\n    history[0].Role.ToString() is \"system\" or \"user\";","tryCatchPattern":null,"preventionTips":["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."],"tags":["mistralai","validation","chat-history","role-ordering"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}