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

  1. Use a ChatHistoryAgentThread with Responses-API agents (OpenAIResponseAgent).
  2. Construct the thread via new ChatHistoryAgentThread() rather than the server-thread factory.
  3. 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

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


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/f73c36b35c0c2798. Report an issue: GitHub.