dotnet/machinelearning · error · NotSupportedException

Only text content is supported, but got {item.GetType().Name

Error message

Only text content is supported, but got {item.GetType().Name}

What it means

The ChatMessage (AutoGen/Semantic Kernel style) overload of BuildPrompt only supports TextContent items inside each message. Any other content item type (images, function-call items, etc.) triggers NotSupportedException with the concrete type name.

Source

Thrown at src/Microsoft.ML.GenAI.Phi/Phi3/Phi3ChatTemplateBuilder.cs:72

        sb.Append("<|assistant|>");
        var input = sb.ToString();

        return input;
    }

    public string BuildPrompt(ChatHistory chatHistory)
    {
        // build prompt from chat history
        var sb = new StringBuilder();

        foreach (var message in chatHistory)
        {
            foreach (var item in message.Items)
            {
                if (item is not TextContent textContent)
                {
                    throw new NotSupportedException($"Only text content is supported, but got {item.GetType().Name}");
                }

                var prompt = message.Role switch
                {
                    _ when message.Role == AuthorRole.System => $"<|system|>{Newline}{textContent}<|end|>{Newline}",
                    _ when message.Role == AuthorRole.User => $"<|user|>{Newline}{textContent}<|end|>{Newline}",
                    _ when message.Role == AuthorRole.Assistant => $"<|assistant|>{Newline}{textContent}<|end|>{Newline}",
                    _ => throw new NotSupportedException($"Unsupported role {message.Role}")
                };

                sb.Append(prompt);
            }
        }

        sb.Append("<|assistant|>");

        return sb.ToString();
    }

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Strip non-text items from message.Items before calling BuildPrompt.
  2. Convert non-text items to text (e.g. describe the image, stringify the function call).
  3. Use a template builder / model that supports the content types you need.

Example fix

// before
var prompt = builder.BuildPrompt(chatHistory);
// after
var textOnly = chatHistory.Select(m => new ChatMessage(m.Role, string.Join("\n", m.Items.OfType<TextContent>().Select(t => t.Text))));
var prompt = builder.BuildPrompt(textOnly);
Defensive patterns

Strategy: validation

Validate before calling

if (chatHistory.SelectMany(m => m.Items).Any(i => i is not TextContent))
    throw new InvalidOperationException("Phi-3 template builder supports text-only chat history.");

Type guard

bool IsTextOnly(ChatMessage m) => m.Items.All(i => i is TextContent);

Try / catch

try { var prompt = builder.BuildPrompt(chatHistory); } catch (NotSupportedException ex) when (ex.Message.StartsWith("Only text content is supported")) { chatHistory = chatHistory.Where(IsTextOnly).ToList(); prompt = builder.BuildPrompt(chatHistory); }

Prevention

When it happens

Trigger: Calling BuildPrompt(IEnumerable<ChatMessage>) where any message's Items collection contains a non-TextContent item — e.g. ImageContent, FunctionCallContent, or a binary content item.

Common situations: Multimodal chat histories (images from vision models) passed to a text-only Phi-3 template builder; tool-call records stored as message items; histories shared with a multimodal agent then reused for Phi-3.

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/11b178c6698825ee. Report an issue: GitHub.