microsoft/semantic-kernel · error · InvalidOperationException

This thread has been deleted and cannot be recreated.

Error message

This thread has been deleted and cannot be recreated.

What it means

Thrown by CreateInternalAsync on OpenAIResponseAgentThread when _isDeleted is true. OpenAIResponseAgentThread is lazily created (its id is the first response id), and after deletion it cannot be recreated — the guard makes that explicit. Normally CreateInternalAsync just returns null (id arrives after the first message).

Source

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

        this._client = client;
        this.ResponseId = responseId;
    }

    /// <summary>
    /// The current response id.
    /// </summary>
    internal string? ResponseId { get; set; }

    /// <inheritdoc />
    public override string? Id => this.ResponseId;

    /// <inheritdoc />
    protected override Task<string?> CreateInternalAsync(CancellationToken cancellationToken = default)
    {
        if (this._isDeleted)
        {
            throw new InvalidOperationException("This thread has been deleted and cannot be recreated.");
        }

        // Id will not be available until after a message is sent
        return Task.FromResult<string?>(null);
    }

    /// <inheritdoc />
    protected override async Task DeleteInternalAsync(CancellationToken cancellationToken = default)
    {
        if (this._isDeleted)
        {
            return;
        }

        if (this.ResponseId is null)
        {
            throw new InvalidOperationException("This thread cannot be deleted, since it has not been created.");
        }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. After deleting, do not reuse the instance — create a new OpenAIResponseAgentThread.
  2. Track deletion state in your application so a deleted thread is replaced, not reused.

Example fix

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

// after
await thread.DeleteAsync();
thread = new OpenAIResponseAgentThread(client);
await agent.InvokeAsync(messages, thread);
Defensive patterns

Strategy: validation

Validate before calling

if (thread.IsDeleted)
{
    thread = new OpenAIResponseAgentThread(client);
}
await agent.InvokeAsync(messages, thread);

Prevention

When it happens

Trigger: await thread.DeleteAsync(); then any later use of the thread that triggers internal creation (e.g. a new invoke that calls EnsureThreadExists → CreateAsync → CreateInternalAsync).

Common situations: Reusing a deleted thread object for a new turn instead of allocating a fresh one.

Related errors


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