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 = True

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. After delete(), construct a new AgentThread subclass instance and call create() on it.
  2. Do not attempt to recreate a deleted thread instance; treat deletion as permanent.
  3. 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

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


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