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
- After deleting, do not reuse the instance — create a new OpenAIResponseAgentThread.
- 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
- Treat a deleted Response thread as terminal; allocate a new one for new conversations.
- Track lifecycle state so deleted threads are replaced, not reused.
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
- This thread cannot be deleted, since it has not been created
- This thread has been deleted and cannot be used anymore.
- This thread has been deleted and cannot be used anymore.
- The thread could not be deleted due to an error response fro
- Thread has been deleted; call `create()` to recreate it.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/2b2fb5c1bdbaf24c.
Report an issue: GitHub.