microsoft/semantic-kernel · error · AgentThreadOperationException

Cannot delete the thread, since it has not been created.

Error message

Cannot delete the thread, since it has not been created.

What it means

Raised as AgentThreadOperationException by ResponseAgentThread._delete() when delete is called but response_id is None (the thread was never actually created — no message was ever sent, so OpenAI never returned an id). Because there is nothing server-side to delete and the local chat history is the only state, the library treats deletion of a never-started thread as an error to surface misuse.

Source

Thrown at python/semantic_kernel/agents/open_ai/openai_responses_agent.py:212

    @override
    async def _create(self) -> str:
        """Starts the thread and returns its ID."""
        if self._is_deleted:
            raise AgentThreadOperationException(
                "Cannot create a new thread, since the current thread has been deleted."
            )
        self._enable_store = True

        # The ID isn't available until after a message is sent
        return ""

    @override
    async def _delete(self) -> None:
        """Ends the current thread."""
        if self._is_deleted:
            return
        if self.response_id is None:
            raise AgentThreadOperationException("Cannot delete the thread, since it has not been created.")
        self._chat_history.clear()
        self._is_deleted = True

    @override
    async def _on_new_message(self, new_message: str | ChatMessageContent) -> None:
        """Called when a new message has been contributed to the chat."""
        if isinstance(new_message, str):
            new_message = ChatMessageContent(role=AuthorRole.USER, content=new_message)

        if not self.response_id:
            self._chat_history.add_message(new_message)

    async def get_messages(
        self, limit: int | None = None, sort_order: Literal["asc", "desc"] | None = "desc"
    ) -> AsyncIterable[ChatMessageContent]:
        """Retrieve the current chat history."""
        if self._is_deleted:
            raise AgentThreadOperationException("Cannot retrieve chat history, since the thread has been deleted.")

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Only call delete() after the thread has an id (i.e., after at least one message was sent and response_id is set).
  2. Guard deletion: if thread.response_id is not None before deleting.
  3. Reorder logic so the user message/invoke precedes teardown.

Example fix

# before
thread = ResponseAgentThread(client=client)
await thread.delete()

# after
thread = ResponseAgentThread(client=client)
await agent.invoke('hello', thread=thread)
await thread.delete()
Defensive patterns

Strategy: validation

Validate before calling

if thread.response_id is None:
    # nothing to delete; skip or send a message first
    pass
else:
    await thread.delete()

Type guard

def response_thread_has_id(thread) -> bool:
    return getattr(thread, 'response_id', None) is not None

Try / catch

from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException
try:
    await thread.delete()
except AgentThreadOperationException as e:
    if 'not been created' in str(e):
        pass  # nothing to delete

Prevention

When it happens

Trigger: Instantiating a ResponseAgentThread and calling delete() before sending any message; a teardown hook running on a thread that never received input; calling delete twice where the first call cleared state incorrectly.

Common situations: Early-exit/exception paths that clean up a thread before first use; session teardown firing on an unused thread; conditional flows where the user message was never sent.

Related errors


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