microsoft/semantic-kernel · error · AgentThreadOperationException
The thread could not be deleted due to an error response fro
Error message
The thread could not be deleted due to an error response from the service.
What it means
Thrown by DeleteInternalAsync when client.DeleteResponseAsync(ResponseId) raises any exception. The raw exception is caught and rewrapped in AgentThreadOperationException, so callers get a consistent error type for thread-service failures. This is a network/service error, distinct from the lifecycle checks (249) that precede it.
Source
Thrown at dotnet/src/Agents/OpenAI/OpenAIResponseAgentThread.cs:84
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.");
}
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)View on GitHub (pinned to c028a0c7dc)
Solutions
- Inspect ex.InnerException for the underlying error and HTTP status.
- Treat 404 (already gone) as success (the resource is effectively deleted).
- Retry transient failures (429/5xx) with backoff.
Example fix
// before
await thread.DeleteAsync(); // may throw AgentThreadOperationException
// after
try { await thread.DeleteAsync(); }
catch (AgentThreadOperationException ex)
{
if (ex.InnerException is ClientResultException cre && (int)cre.Status == 404) return; // already gone
logger.LogError(ex.InnerException, "delete failed");
throw;
} Defensive patterns
Strategy: retry
Validate before calling
// Retry transient delete failures with backoff
static async Task SafeDeleteAsync(OpenAIResponseAgentThread thread, int attempts = 3)
{
for (int i = 0; i < attempts; i++)
{
try { await thread.DeleteAsync(); return; }
catch (AgentThreadOperationException ex) when (ex.InnerException is ClientResultException c && (int)c.Status == 404) { return; }
catch (AgentThreadOperationException) when (i < attempts - 1) { await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))); }
}
} Try / catch
try { await thread.DeleteAsync(); }
catch (AgentThreadOperationException ex)
{
if (ex.InnerException is ClientResultException cre && (int)cre.Status == 404) return; // already gone
logger.LogError(ex.InnerException, "delete failed");
throw;
} Prevention
- Treat 404 on delete as success (resource is effectively deleted).
- Retry 429/5xx delete failures with exponential backoff.
- Log ex.InnerException to capture the real HTTP status.
When it happens
Trigger: Calling thread.DeleteAsync() on a valid Response thread while the OpenAI service rejects the delete — auth failure, rate limit, the response was already deleted server-side, network timeout, etc.
Common situations: Expired/revoked API key at cleanup time; 429 during teardown; the stored response no longer exists server-side (already purged); intermittent network issues.
Related errors
- The message could not be added to the thread due to an error
- This thread has been deleted and cannot be recreated.
- This thread cannot be deleted, since it has not been created
- This thread has been deleted and cannot be used anymore.
- The thread could not be created due to an error response fro
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e74f6aef69ba8856.
Report an issue: GitHub.