microsoft/semantic-kernel · warning · AgentThreadOperationException
The thread cannot be deleted because it has not been created
Error message
The thread cannot be deleted because it has not been created yet.
What it means
Raised by AzureAIAgentThread._delete when self._id is None, meaning the thread was constructed without an existing thread_id and _create was never successfully called. You cannot delete a thread that has no server-side identity. Surfaced as AgentThreadOperationException.
Source
Thrown at python/semantic_kernel/agents/azure_ai/azure_ai_agent.py:311
async def _create(self) -> str:
"""Starts the thread and returns its ID."""
try:
response = await self._client.agents.threads.create(
messages=self._messages,
metadata=self._metadata,
tool_resources=self._tool_resources,
)
except Exception as ex:
raise AgentThreadOperationException(
"The thread could not be created due to an error response from the service."
) from ex
return response.id
@override
async def _delete(self) -> None:
"""Ends the current thread."""
if self._id is None:
raise AgentThreadOperationException("The thread cannot be deleted because it has not been created yet.")
try:
await self._client.agents.threads.delete(self._id)
except Exception as ex:
raise AgentThreadOperationException(
"The thread could not be deleted due to an error response from the service."
) from ex
@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 new_message.metadata
or "thread_id" not in new_message.metadata
or new_message.metadata["thread_id"] != self.id
):View on GitHub (pinned to c028a0c7dc)
Solutions
- Guard the delete: only call delete() if thread.id is not None (i.e. it was created or supplied).
- Ensure create() succeeded before scheduling deletion; check the return of create().
- In cleanup/finally blocks, check thread._id or thread.id before invoking delete().
Example fix
// before
thread = AzureAIAgentThread(client=client)
await thread.delete() // _id is None
// after
thread = AzureAIAgentThread(client=client)
await thread.create() // assigns _id
if thread.id is not None:
await thread.delete() Defensive patterns
Strategy: validation
Validate before calling
async def safe_delete(thread):
if getattr(thread, '_id', None) is None:
return # nothing to delete
await thread.delete() Type guard
def thread_has_id(thread) -> bool:
return getattr(thread, '_id', None) is not None Try / catch
try:
await thread.delete()
except AgentThreadOperationException as e:
if 'has not been created' in str(e):
return # benign: nothing to delete
raise Prevention
- Only call delete() after a successful create() or when a thread_id was supplied.
- Guard cleanup/finally blocks with a thread.id check.
- Treat 'not created yet' as a benign no-op in cleanup paths.
When it happens
Trigger: Constructing AzureAIAgentThread(client=c) with no thread_id, then immediately calling delete() without first calling create(); calling delete after a failed create() that left _id as None; double lifecycle management where one path deletes before creation.
Common situations: Error-handling/cleanup code that unconditionally calls delete in a finally block before the thread was created; race where create() threw (see error 745) but cleanup proceeds to delete(); confusing a locally-constructed thread with a remote one.
Related errors
- The thread has been deleted.
- The thread could not be deleted due to an error response fro
- This thread has been deleted and cannot be used anymore.
- This thread has been deleted and cannot be recreated.
- This thread cannot be deleted, since it has not been created
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/4953a9c39ece1f4b.
Report an issue: GitHub.