microsoft/semantic-kernel · error · 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 as AgentThreadOperationException by AssistantAgentThread._delete when self._id is None, meaning the thread was never created (create() not called or failed) before delete was invoked. The SDK guards against sending a delete request with no thread id.
Source
Thrown at python/semantic_kernel/agents/open_ai/openai_assistant_agent.py:186
async def _create(self) -> str:
"""Starts the thread and returns its ID."""
try:
response = await self._client.beta.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.beta.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)
# Only add the message to the thread if it's not already there
if (
not new_message.metadata
or "thread_id" not in new_message.metadata
or new_message.metadata["thread_id"] != self._idView on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure create() succeeds before calling delete(); only delete when thread.id is not None.
- In cleanup blocks, guard: if thread.id is not None: await thread.delete().
- Handle create() failures so delete is not reached with no id.
Example fix
# before
await thread.create() # may have failed
await thread.delete() # _id None -> error
# after
await thread.create()
if thread.id is not None:
await thread.delete() Defensive patterns
Strategy: validation
Validate before calling
# only delete when the thread actually exists
if thread.id is not None:
await thread.delete()
else:
logging.warning("Skipping delete: thread was never created.") Type guard
def thread_is_created(thread) -> bool:
return getattr(thread, "_id", None) is not None Prevention
- Guard delete() with a check on thread.id.
- In finally/cleanup blocks, only delete when creation succeeded.
- Handle create() failures so delete is not reached.
When it happens
Trigger: Calling thread.delete() before thread.create() has successfully set an id, or after a prior create() failed so _id remained None.
Common situations: Forgetting to create the thread in a flow that only deletes; an earlier create() raised and the code continued to delete; deleting in a cleanup/finally block without checking creation succeeded.
Related errors
- Client cannot be None
- Missing or malformed 'vector_store_ids' in: {spec}
- Tool spec must include a 'type' field.
- Unsupported tool type: {spec.type}
- The thread could not be created due to an error response fro
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/5dc84071eb27bf0e.
Report an issue: GitHub.