{"record":{"id":"14a8548c18d69882","repo":"microsoft/semantic-kernel","slug":"cannot-create-a-thread-that-has-been-deleted","errorCode":null,"errorMessage":"Cannot create a thread that has been deleted.","messagePattern":"Cannot create a thread that has been deleted\\.","errorType":"exception","errorClass":"AgentThreadOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/copilot_studio/copilot_studio_agent.py","lineNumber":238,"sourceCode":"        \"\"\"Get the conversation ID.\"\"\"\n        return self._conversation_id\n\n    @conversation_id.setter\n    def conversation_id(self, value: str | None) -> None:\n        \"\"\"Set the conversation ID.\"\"\"\n        self._conversation_id = value\n\n    @override\n    @property\n    def id(self) -> str | None:\n        \"\"\"Get the thread ID.\"\"\"\n        return self.conversation_id\n\n    @override\n    async def _create(self) -> str:\n        # Creation is deferred to CopilotStudioAgent._ensure_conversation.\n        if self._is_deleted:\n            raise AgentThreadOperationException(\"Cannot create a thread that has been deleted.\")\n        return \"\"\n\n    @override\n    async def _delete(self) -> None:\n        if self._is_deleted:\n            return\n        if self.conversation_id is None:\n            raise AgentThreadOperationException(\"Cannot delete the thread, since it has not been created.\")\n        self._conversation_id = None\n        self._is_deleted = True\n\n    @override\n    async def _on_new_message(self, new_message: ChatMessageContent) -> None:\n        raise NotImplementedError(\n            \"This method is not implemented for CopilotStudioAgent. \"\n            \"Messages and responses are automatically handled by the Copilot Agent.\"\n        )\n","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/copilot_studio/copilot_studio_agent.py#L220-L256","documentation":"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.","triggerScenarios":"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.","commonSituations":"Reusing a thread object across multiple conversation lifecycles after explicitly deleting it; cleanup logic that deletes threads eagerly but then retries the conversation.","solutions":["Create a fresh CopilotStudioAgentThread after deleting the previous one.","If you need a new conversation, construct a new thread with CopilotStudioAgentThread(agent.client) rather than resurrecting a deleted one.","Audit cleanup/retry code paths to ensure deleted threads are not reused."],"exampleFix":"# before\nawait thread.delete()\nawait agent.get_response(\"hello\", thread=thread)  # raises\n\n# after\nawait thread.delete()\nthread = CopilotStudioAgentThread(agent.client)  # fresh thread\nawait agent.get_response(\"hello\", thread=thread)","handlingStrategy":"validation","validationCode":"if getattr(thread, '_is_deleted', False):\n    thread = CopilotStudioAgentThread(agent.client)  # start fresh\nawait agent.get_response(\"hello\", thread=thread)","typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException\n\ntry:\n    await agent.get_response(\"hello\", thread=old_thread)\nexcept AgentThreadOperationException:\n    thread = CopilotStudioAgentThread(agent.client)\n    await agent.get_response(\"hello\", thread=thread)","preventionTips":["Never reuse a thread after calling delete() — create a new one.","Track thread lifecycle state in your session management code.","Audit retry/error-handling paths to avoid passing deleted threads."],"tags":["thread","lifecycle","copilot-studio"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}