microsoft/semantic-kernel · error · AgentThreadOperationException

Cannot create a thread that has been deleted.

Error message

Cannot create a thread that has been deleted.

What it means

Raised by CopilotStudioAgentThread._create() when _is_deleted is True. CopilotStudioAgentThread defers real creation to CopilotStudioAgent._ensure_conversation, so _create() normally just returns an empty string — but after _delete() has run (which sets _is_deleted=True and clears conversation_id), any subsequent creation attempt is rejected. This is an AgentThreadOperationException.

Source

Thrown at python/semantic_kernel/agents/copilot_studio/copilot_studio_agent.py:238

        """Get the conversation ID."""
        return self._conversation_id

    @conversation_id.setter
    def conversation_id(self, value: str | None) -> None:
        """Set the conversation ID."""
        self._conversation_id = value

    @override
    @property
    def id(self) -> str | None:
        """Get the thread ID."""
        return self.conversation_id

    @override
    async def _create(self) -> str:
        # Creation is deferred to CopilotStudioAgent._ensure_conversation.
        if self._is_deleted:
            raise AgentThreadOperationException("Cannot create a thread that has been deleted.")
        return ""

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

    @override
    async def _on_new_message(self, new_message: ChatMessageContent) -> None:
        raise NotImplementedError(
            "This method is not implemented for CopilotStudioAgent. "
            "Messages and responses are automatically handled by the Copilot Agent."
        )

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Create a fresh CopilotStudioAgentThread after deleting the previous one.
  2. If you need a new conversation, construct a new thread with CopilotStudioAgentThread(agent.client) rather than resurrecting a deleted one.
  3. Audit cleanup/retry code paths to ensure deleted threads are not reused.

Example fix

# before
await thread.delete()
await agent.get_response("hello", thread=thread)  # raises

# after
await thread.delete()
thread = CopilotStudioAgentThread(agent.client)  # fresh thread
await agent.get_response("hello", thread=thread)
Defensive patterns

Strategy: validation

Validate before calling

if getattr(thread, '_is_deleted', False):
    thread = CopilotStudioAgentThread(agent.client)  # start fresh
await agent.get_response("hello", thread=thread)

Try / catch

from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException

try:
    await agent.get_response("hello", thread=old_thread)
except AgentThreadOperationException:
    thread = CopilotStudioAgentThread(agent.client)
    await agent.get_response("hello", thread=thread)

Prevention

When it happens

Trigger: Calling agent.invoke()/get_response()/invoke_stream() with a thread that was already deleted via thread.delete(). The base AgentThread machinery calls _create() during _ensure_thread_exists_with_messages, hitting the guard.

Common situations: Reusing a thread object across multiple conversation lifecycles after explicitly deleting it; cleanup logic that deletes threads eagerly but then retries the conversation.

Related errors


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