dotnet/machinelearning · error · InvalidOperationException
Please provide a message with content.
Error message
Please provide a message with content.
What it means
The Llama 3.1 chat template builder requires every message to carry non-null content, because the LLaMA prompt format embeds each message's text between header/eot tags. It throws InvalidOperationException when any IMessage in the sequence returns null from GetContent().
Source
Thrown at src/Microsoft.ML.GenAI.LLaMA/Llama3_1ChatTemplateBuilder.cs:25
using Microsoft.Extensions.AI;
using Microsoft.ML.GenAI.Core;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using TextContent = Microsoft.SemanticKernel.TextContent;
namespace Microsoft.ML.GenAI.LLaMA;
#pragma warning disable MSML_GeneralName // This name should be PascalCased
public class Llama3_1ChatTemplateBuilder : IChatTemplateBuilder, IMEAIChatTemplateBuilder
#pragma warning restore MSML_GeneralName // This name should be PascalCased
{
private const char Newline = '\n';
public string BuildPrompt(IEnumerable<IMessage> messages, IEnumerable<FunctionContract>? tools = null)
{
var availableRoles = new[] { Role.System, Role.User, Role.Assistant };
if (messages.Any(m => m.GetContent() is null))
{
throw new InvalidOperationException("Please provide a message with content.");
}
if (messages.Any(m => m.GetRole() is null || availableRoles.Contains(m.GetRole()!.Value) == false))
{
throw new InvalidOperationException("Please provide a message with a valid role. The valid roles are System, User, and Assistant.");
}
// construct template based on instruction from
// https://github.com/meta-llama/llama3/blob/11817d47e1ba7a4959b025eb1ca308572e0e3963/llama/generation.py#L280
var sb = new StringBuilder();
sb.Append("<|begin_of_text|>");
foreach (var message in messages)
{
var role = message.GetRole()!.Value;
var content = message.GetContent()!;
sb.Append(message switch
{View on GitHub (pinned to 7b76e69cf9)
Solutions
- Filter or skip messages with null content before calling BuildPrompt.
- Replace null content with an empty string or a descriptive placeholder if the message must be kept.
- Ensure upstream message-construction code always sets non-null content.
- Convert non-text messages (tool calls, images) to their text representation before building the prompt.
Example fix
// before var prompt = builder.BuildPrompt(messages); // after var prompt = builder.BuildPrompt(messages.Where(m => m.GetContent() is not null));
Defensive patterns
Strategy: validation
Validate before calling
if (messages.Any(m => m.GetContent() is null))
throw new InvalidOperationException("All messages must have non-null content before BuildPrompt."); Type guard
static bool HasContent(IMessage m) => m.GetContent() is not null; var safe = messages.Where(HasContent);
Try / catch
try { prompt = builder.BuildPrompt(messages); }
catch (InvalidOperationException ex) when (ex.Message.Contains("content"))
{ prompt = builder.BuildPrompt(messages.Where(m => m.GetContent() is not null)); } Prevention
- Sanitize chat history (drop or fill null-content messages) at pipeline entry.
- Convert tool-call/image messages to text before LLaMA prompt building.
- Unit-test the template builder with realistic histories including tool messages.
When it happens
Trigger: Calling BuildPrompt(IEnumerable<IMessage>, ...) with a message whose GetContent() is null — e.g. a message constructed without content, a tool/function-call message whose payload is not text, or a message deserialized with a missing content field.
Common situations: Feeding tool-call or image messages into the text-only LLaMA template; constructing TextMessage with a null body from an upstream model response; pipeline stages that emit role-only placeholder messages.
Related errors
- Please provide a message with a valid role. The valid roles
- Invalid role.
- Expected either {0} or {1} to be provided
- {nameof(numberOfCVFolds)} must be at least 2
- Duplicate column name {duplicateColName} is present in two o
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/ac2bd0807a0ea3ce.
Report an issue: GitHub.