microsoft/semantic-kernel · error · RuntimeError
Cannot create thread because it has already been deleted.
Error message
Cannot create thread because it has already been deleted.
What it means
AgentThread.create() refuses to run on an instance whose _is_deleted flag is True — deletion is irreversible for that instance. This pairs with error 693: once a thread is deleted you cannot revive it; you must build a brand-new thread object. The guard prevents ambiguous half-deleted state.
Source
Thrown at python/semantic_kernel/agents/agent.py:130
"""Base class for agent threads."""
def __init__(self):
"""Initialize the agent thread."""
self._is_deleted: bool = False # type: ignore
self._id: str | None = None # type: ignore
@property
def id(self) -> str | None:
"""Returns the ID of the current thread (if any)."""
if self._is_deleted:
raise RuntimeError("Thread has been deleted; call `create()` to recreate it.")
return self._id
async def create(self) -> str | None:
"""Starts the thread and returns the thread ID."""
# A thread should not be recreated after it has been deleted.
if self._is_deleted:
raise RuntimeError("Cannot create thread because it has already been deleted.")
# If the thread ID is already set, we're done, just return the Id.
if self.id is not None:
return self.id
# Otherwise, create the thread.
self._id = await self._create()
return self.id
async def delete(self) -> None:
"""Ends the current thread."""
# A thread should not be deleted if it has already been deleted.
if self._is_deleted:
return
# If the thread ID is not set, we're done, just return.
if self.id is None:
self._is_deleted = TrueView on GitHub (pinned to c028a0c7dc)
Solutions
- After delete(), construct a new AgentThread subclass instance and call create() on it.
- Do not attempt to recreate a deleted thread instance; treat deletion as permanent.
- Set the old reference to None and allocate a fresh thread for the next conversation.
Example fix
# before await thread.delete() await thread.create() # RuntimeError # after await thread.delete() thread = MyAgentThread() # new instance await thread.create()
Defensive patterns
Strategy: validation
Validate before calling
if getattr(thread, '_is_deleted', False):
# build a brand-new thread instance; do not call create() on this one
thread = MyAgentThread()
await thread.create() Type guard
def thread_is_deleted(thread) -> bool:
return getattr(thread, '_is_deleted', False) Try / catch
try:
await thread.create()
except RuntimeError as e:
if 'already been deleted' in str(e):
thread = MyAgentThread() # new instance
await thread.create()
else:
raise Prevention
- Treat deletion as permanent for that instance.
- Construct a new AgentThread subclass after delete().
- Null stale references.
- Don't put create() inside generic retry-on-failure loops that may follow a delete.
When it happens
Trigger: Calling await thread.create() on the same instance after await thread.delete(); reusing a thread variable across a delete/create cycle.
Common situations: Trying to 'reset' a conversation by recreating the same thread; generic retry logic that calls create() again after a failure that triggered deletion.
Related errors
- Thread has been deleted; call `create()` to recreate it.
- 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
- This thread has been deleted and cannot be used anymore.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/508eb2750ccd34bc.
Report an issue: GitHub.