{"record":{"id":"19e4f922e3241df2","repo":"microsoft/semantic-kernel","slug":"this-thread-cannot-be-deleted-since-it-has-not-be-19e4f9","errorCode":null,"errorMessage":"This thread cannot be deleted, since it has not been created.","messagePattern":"This thread cannot be deleted, since it has not been created\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Agents/OpenAI/OpenAIResponseAgentThread.cs","lineNumber":75,"sourceCode":"        {\n            throw new InvalidOperationException(\"This thread has been deleted and cannot be recreated.\");\n        }\n\n        // Id will not be available until after a message is sent\n        return Task.FromResult<string?>(null);\n    }\n\n    /// <inheritdoc />\n    protected override async Task DeleteInternalAsync(CancellationToken cancellationToken = default)\n    {\n        if (this._isDeleted)\n        {\n            return;\n        }\n\n        if (this.ResponseId is null)\n        {\n            throw new InvalidOperationException(\"This thread cannot be deleted, since it has not been created.\");\n        }\n\n        try\n        {\n            await this._client.DeleteResponseAsync(this.ResponseId, cancellationToken).ConfigureAwait(false);\n        }\n        catch (Exception ex)\n        {\n            throw new AgentThreadOperationException(\"The thread could not be deleted due to an error response from the service.\", ex);\n        }\n\n        this._isDeleted = true;\n    }\n\n    /// <inheritdoc/>\n    protected override Task OnNewMessageInternalAsync(ChatMessageContent newMessage, CancellationToken cancellationToken = default)\n    {\n        if (this._isDeleted)","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Agents/OpenAI/OpenAIResponseAgentThread.cs#L57-L93","documentation":"Thrown by DeleteInternalAsync on OpenAIResponseAgentThread when ResponseId is null. Unlike assistant threads, a Response thread's identity is the id of the first response, which only exists after a message has been sent. Deleting before any response was created has nothing to delete, so the library throws InvalidOperationException.","triggerScenarios":"new OpenAIResponseAgentThread(client); then immediately await thread.DeleteAsync(); without ever invoking the agent (so no ResponseId was ever assigned).","commonSituations":"Cleanup/dispose logic that unconditionally deletes a thread, including the never-used case; aborting a conversation before the first message round-trip.","solutions":["Only delete after a response exists — check that thread.Id (the ResponseId) is non-null before calling DeleteAsync.","Guard cleanup: if (thread.Id is not null) await thread.DeleteAsync();","For early-abort flows, simply drop the reference instead of deleting."],"exampleFix":"// before\nvar thread = new OpenAIResponseAgentThread(client);\n// user cancels before any message...\nawait thread.DeleteAsync(); // throws — nothing to delete\n\n// after\nif (!string.IsNullOrEmpty(thread.Id))\n{\n    await thread.DeleteAsync();\n}","handlingStrategy":"validation","validationCode":"if (!string.IsNullOrEmpty(thread.Id))\n{\n    await thread.DeleteAsync();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only delete a Response thread after it has an Id (a response was created).","Make cleanup conditional on Id being present.","For early aborts, drop the reference instead of deleting."],"tags":["thread","lifecycle","responses-api","agents","validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}