microsoft/semantic-kernel · error · InvalidOperationException

This thread cannot be deleted, since it has not been created

Error message

This thread cannot be deleted, since it has not been created.

What it means

Thrown by AgentThread.DeleteAsync when the thread was never created on the backend (this.Id is null). The base AgentThread lifecycle requires that CreateAsync (or a resume-from-existing-id constructor) has run first, setting the Id property, before deletion is meaningful. The method short-circuits with a no-op if already deleted, but rejects deletion of a never-started thread.

Source

Thrown at dotnet/src/Agents/Abstractions/AgentThread.cs:116

#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
    }

    /// <summary>
    /// Deletes the current thread.
    /// </summary>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
    /// <returns>A task that completes when the thread has been deleted.</returns>
    /// <exception cref="InvalidOperationException">The thread was never created.</exception>
    public virtual async Task DeleteAsync(CancellationToken cancellationToken = default)
    {
        if (this.IsDeleted)
        {
            return;
        }

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

#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
        await this.AIContextProviders.ConversationDeletingAsync(this.Id, cancellationToken).ConfigureAwait(false);
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

        await this.DeleteInternalAsync(cancellationToken).ConfigureAwait(false);

        this.IsDeleted = true;
    }

    /// <summary>
    /// This method is called when a new message has been contributed to the chat by any participant.
    /// </summary>
    /// <remarks>
    /// Inheritors can use this method to update their context based on the new message.
    /// </remarks>
    /// <param name="newMessage">The new message.</param>

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Check thread.Id is not null before calling DeleteAsync, or call CreateAsync first.
  2. Guard with: if (!thread.IsDeleted && thread.Id is not null) await thread.DeleteAsync(ct);
  3. Restructure cleanup logic so DeleteAsync only runs in a finally block when creation has already succeeded.

Example fix

// before
var thread = new AzureAIAgentThread(client);
await thread.DeleteAsync(ct); // throws

// after
var thread = new AzureAIAgentThread(client);
if (thread.Id is not null && !thread.IsDeleted)
{
    await thread.DeleteAsync(ct);
}
Defensive patterns

Strategy: validation

Validate before calling

if (thread is { IsDeleted: false, Id: null })
{
    // Thread was never created; skip or create first
    return; // or await thread.CreateAsync(ct);
}

Try / catch

try
{
    await thread.DeleteAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("has not been created"))
{
    // Thread was never created; nothing to clean up
    _logger.LogDebug("Thread was never created, skipping deletion.");
}

Prevention

When it happens

Trigger: Calling thread.DeleteAsync() on a fresh AgentThread instance whose CreateAsync was never invoked and that was not constructed with an existing thread Id. This can also happen if the first message that would trigger lazy creation (via OnNewMessageAsync) was never sent.

Common situations: Developer creates an AzureAIAgentThread(client) (no id overload), then immediately calls DeleteAsync without ever invoking the agent or calling CreateAsync. Also occurs in cleanup/disposal paths that run even when the main workflow threw before thread creation.

Related errors


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