microsoft/semantic-kernel · error · InvalidOperationException

This thread has been deleted and cannot be used anymore.

Error message

This thread has been deleted and cannot be used anymore.

What it means

Thrown by OnNewMessageInternalAsync on OpenAIResponseAgentThread when _isDeleted is true. Once deleted, the thread refuses any new message. This mirrors the deleted-thread guard on the other thread types (241/252).

Source

Thrown at dotnet/src/Agents/OpenAI/OpenAIResponseAgentThread.cs:95

        try
        {
            await this._client.DeleteResponseAsync(this.ResponseId, cancellationToken).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            throw new AgentThreadOperationException("The thread could not be deleted due to an error response from the service.", ex);
        }

        this._isDeleted = true;
    }

    /// <inheritdoc/>
    protected override Task OnNewMessageInternalAsync(ChatMessageContent newMessage, CancellationToken cancellationToken = default)
    {
        if (this._isDeleted)
        {
            throw new InvalidOperationException("This thread has been deleted and cannot be used anymore.");
        }

        return Task.CompletedTask;
    }

    /// <inheritdoc />
    public async IAsyncEnumerable<ChatMessageContent> GetMessagesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        if (this._isDeleted)
        {
            throw new InvalidOperationException("This thread has been deleted and cannot be used anymore.");
        }

        if (!string.IsNullOrEmpty(this.ResponseId))
        {
            var collectionResult = this._client.GetResponseInputItemsAsync(this.ResponseId, cancellationToken).ConfigureAwait(false);
            await foreach (var responseItem in collectionResult)
            {

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Check thread.IsDeleted before sending new messages.
  2. Create a fresh OpenAIResponseAgentThread for a new conversation.

Example fix

// before
await thread.DeleteAsync();
await agent.InvokeAsync(msg, thread); // throws

// after
if (thread.IsDeleted) thread = new OpenAIResponseAgentThread(client);
await agent.InvokeAsync(msg, thread);
Defensive patterns

Strategy: validation

Validate before calling

if (!thread.IsDeleted)
{
    await agent.InvokeAsync(newMessage, thread);
}

Prevention

When it happens

Trigger: await thread.DeleteAsync(); then await agent.InvokeAsync(newMessage, thread); (or thread.OnNewMessageAsync) which routes through OnNewMessageInternalAsync.

Common situations: Conversation-end cleanup followed by a late inbound message; reusing a deleted Response thread.

Related errors


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