microsoft/semantic-kernel · error · AgentThreadOperationException
Cannot delete the thread, since it has not been created.
Error message
Cannot delete the thread, since it has not been created.
What it means
Raised by CopilotStudioAgentThread._delete() when conversation_id is None and the thread has not already been deleted. Since _delete() is idempotent for already-deleted threads (early return), this error only fires on the first delete attempt of a thread that never had a conversation started. It is an AgentThreadOperationException.
Source
Thrown at python/semantic_kernel/agents/copilot_studio/copilot_studio_agent.py:246
@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."
)
@experimental
class CopilotStudioAgent(Agent):
"""Semantic Kernel abstraction over a Copilot Studio Agent."""
client: CopilotClient
channel_type: ClassVar[type[AgentChannel] | None] = None
View on GitHub (pinned to c028a0c7dc)
Solutions
- Guard the delete call: only delete if thread.conversation_id is not None.
- Move thread creation closer to first use so it is always populated before cleanup.
- Let the agent manage the thread lifecycle by not passing an explicit thread, so there is nothing to manually delete.
Example fix
# before
thread = CopilotStudioAgentThread(agent.client)
await thread.delete() # raises — never started
# after
thread = CopilotStudioAgentThread(agent.client)
if thread.conversation_id is not None:
await thread.delete() Defensive patterns
Strategy: validation
Validate before calling
if thread.conversation_id is not None:
await thread.delete() Try / catch
from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException
try:
await thread.delete()
except AgentThreadOperationException:
pass # nothing to delete; safe to ignore Prevention
- Guard delete calls with a conversation_id check.
- Use try/except AgentThreadOperationException in cleanup/finally blocks.
- Create threads lazily, only when the conversation is actually about to start.
When it happens
Trigger: Constructing a CopilotStudioAgentThread and calling thread.delete() before any agent invocation that would populate conversation_id via _ensure_conversation.
Common situations: Cleanup/teardown in a finally block that runs even when the conversation was never started; early-exit error paths that attempt to delete a thread that was created but never used.
Related errors
- Cannot create a thread that has been deleted.
- 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/12a095187af4ee8e.
Report an issue: GitHub.