{"record":{"id":"4953a9c39ece1f4b","repo":"microsoft/semantic-kernel","slug":"the-thread-cannot-be-deleted-because-it-has-not-be","errorCode":null,"errorMessage":"The thread cannot be deleted because it has not been created yet.","messagePattern":"The thread cannot be deleted because it has not been created yet\\.","errorType":"exception","errorClass":"AgentThreadOperationException","httpStatus":null,"severity":"warning","filePath":"python/semantic_kernel/agents/azure_ai/azure_ai_agent.py","lineNumber":311,"sourceCode":"    async def _create(self) -> str:\n        \"\"\"Starts the thread and returns its ID.\"\"\"\n        try:\n            response = await self._client.agents.threads.create(\n                messages=self._messages,\n                metadata=self._metadata,\n                tool_resources=self._tool_resources,\n            )\n        except Exception as ex:\n            raise AgentThreadOperationException(\n                \"The thread could not be created due to an error response from the service.\"\n            ) from ex\n        return response.id\n\n    @override\n    async def _delete(self) -> None:\n        \"\"\"Ends the current thread.\"\"\"\n        if self._id is None:\n            raise AgentThreadOperationException(\"The thread cannot be deleted because it has not been created yet.\")\n        try:\n            await self._client.agents.threads.delete(self._id)\n        except Exception as ex:\n            raise AgentThreadOperationException(\n                \"The thread could not be deleted due to an error response from the service.\"\n            ) from ex\n\n    @override\n    async def _on_new_message(self, new_message: str | ChatMessageContent) -> None:\n        \"\"\"Called when a new message has been contributed to the chat.\"\"\"\n        if isinstance(new_message, str):\n            new_message = ChatMessageContent(role=AuthorRole.USER, content=new_message)\n\n        if (\n            not new_message.metadata\n            or \"thread_id\" not in new_message.metadata\n            or new_message.metadata[\"thread_id\"] != self.id\n        ):","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/azure_ai/azure_ai_agent.py#L293-L329","documentation":"Raised by AzureAIAgentThread._delete when self._id is None, meaning the thread was constructed without an existing thread_id and _create was never successfully called. You cannot delete a thread that has no server-side identity. Surfaced as AgentThreadOperationException.","triggerScenarios":"Constructing AzureAIAgentThread(client=c) with no thread_id, then immediately calling delete() without first calling create(); calling delete after a failed create() that left _id as None; double lifecycle management where one path deletes before creation.","commonSituations":"Error-handling/cleanup code that unconditionally calls delete in a finally block before the thread was created; race where create() threw (see error 745) but cleanup proceeds to delete(); confusing a locally-constructed thread with a remote one.","solutions":["Guard the delete: only call delete() if thread.id is not None (i.e. it was created or supplied).","Ensure create() succeeded before scheduling deletion; check the return of create().","In cleanup/finally blocks, check thread._id or thread.id before invoking delete()."],"exampleFix":"// before\nthread = AzureAIAgentThread(client=client)\nawait thread.delete()  // _id is None\n// after\nthread = AzureAIAgentThread(client=client)\nawait thread.create()   // assigns _id\nif thread.id is not None:\n    await thread.delete()","handlingStrategy":"validation","validationCode":"async def safe_delete(thread):\n    if getattr(thread, '_id', None) is None:\n        return  # nothing to delete\n    await thread.delete()","typeGuard":"def thread_has_id(thread) -> bool:\n    return getattr(thread, '_id', None) is not None","tryCatchPattern":"try:\n    await thread.delete()\nexcept AgentThreadOperationException as e:\n    if 'has not been created' in str(e):\n        return  # benign: nothing to delete\n    raise","preventionTips":["Only call delete() after a successful create() or when a thread_id was supplied.","Guard cleanup/finally blocks with a thread.id check.","Treat 'not created yet' as a benign no-op in cleanup paths."],"tags":["azure-ai","thread","lifecycle","state-management"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}