microsoft/semantic-kernel · error · InvalidOperationException
The agent thread is not a ChatHistoryAgentThread.
Error message
The agent thread is not a ChatHistoryAgentThread.
What it means
ResponseThreadActions.GetChatHistory expects an AgentThread of the concrete type ChatHistoryAgentThread so it can read its .ChatHistory. Any other AgentThread subclass (e.g., OpenAIAssistantAgentThread) lacks that property and throws InvalidOperationException.
Source
Thrown at dotnet/src/Agents/OpenAI/Internal/ResponseThreadActions.cs:309
content: null)
{
ModelId = modelId,
InnerContent = functionCallUpdateContent,
Items = [functionCallUpdateContent],
};
overrideHistory.Add(functionResultMessage);
yield return streamingFunctionResultMessage;
}
}
private static ChatHistory GetChatHistory(AgentThread agentThread)
{
if (agentThread is ChatHistoryAgentThread chatHistoryAgentThread)
{
return chatHistoryAgentThread.ChatHistory;
}
throw new InvalidOperationException("The agent thread is not a ChatHistoryAgentThread.");
}
private static void ThrowIfIncompleteOrFailed(OpenAIResponseAgent agent, ResponseResult response)
{
if (response.Status is ResponseStatus.Incomplete or ResponseStatus.Failed)
{
throw new KernelException(
$"Run failed with status: `{response.Status}` for agent `{agent.Name}` with error: {response.Error.Message} or incomplete details: {response.IncompleteStatusDetails.Reason}");
}
}
/// <summary>
/// Processes a function result and returns a string representation.
/// The OpenAI Responses API does not support multimodal tool results, so ImageContent returns an error message.
/// </summary>
internal static string GetFunctionResultAsString(object? result)
{
var processed = FunctionCallsProcessor.ProcessFunctionResult(result ?? string.Empty);View on GitHub (pinned to c028a0c7dc)
Solutions
- Use a ChatHistoryAgentThread with Responses-API agents (OpenAIResponseAgent).
- Construct the thread via new ChatHistoryAgentThread() rather than the server-thread factory.
- Confirm the agent type and thread type are compatible before invoking.
Example fix
// before
AgentThread thread = new OpenAIAssistantAgentThread(client);
await foreach (var r in responseAgent.InvokeAsync(thread)) { }
// after
AgentThread thread = new ChatHistoryAgentThread();
await foreach (var r in responseAgent.InvokeAsync(thread)) { } Defensive patterns
Strategy: type-guard
Type guard
static bool IsChatHistoryThread(AgentThread t) => t is ChatHistoryAgentThread;
Try / catch
try { var history = GetChatHistory(thread); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not a ChatHistoryAgentThread")) {
thread = new ChatHistoryAgentThread(); // create a compatible thread
} Prevention
- Use ChatHistoryAgentThread with Responses-API agents.
- Do not reuse Assistant-API server threads with Responses paths.
- Document which thread type each agent expects.
When it happens
Trigger: Passing a non-ChatHistoryAgentThread (a server-backed OpenAIAssistantAgentThread or a custom AgentThread) into a code path that needs local chat history.
Common situations: Mixing the Assistant-API server thread model with the Responses-API code path; reusing a thread object across incompatible agent types.
Related errors
- Unsupported role {message.Role.Label}. Only system, user, de
- OPENAI_API_KEY is not set.
- Invalid OpenAI client type '{connection.Type}' was specified
- Unsupported content type {content.GetType().Name}. Cannot co
- ImageContent cannot be converted to ResponseContentPart. Onl
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/f73c36b35c0c2798.
Report an issue: GitHub.