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

  1. Inspect ex.InnerException for the underlying error and HTTP status.
  2. Treat 404 (already gone) as success (the resource is effectively deleted).
  3. 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

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


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