{"record":{"id":"b6bd8a0cf872a5ee","repo":"microsoft/semantic-kernel","slug":"the-thread-has-been-deleted","errorCode":null,"errorMessage":"The thread has been deleted.","messagePattern":"The thread has been deleted\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"python/semantic_kernel/agents/azure_ai/azure_ai_agent.py","lineNumber":343,"sourceCode":"        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        ):\n            assert self.id is not None  # nosec\n            await AgentThreadActions.create_message(self._client, self.id, new_message)\n\n    async def get_messages(self, sort_order: Literal[\"asc\", \"desc\"] = \"desc\") -> AsyncIterable[ChatMessageContent]:\n        \"\"\"Get the messages in the thread.\n\n        Args:\n            sort_order: The order to sort the messages in. Either \"asc\" or \"desc\".\n\n        Yields:\n            An AsyncIterable of ChatMessageContent of the messages in the thread.\n        \"\"\"\n        if self._is_deleted:\n            raise ValueError(\"The thread has been deleted.\")\n        if self._id is None:\n            await self.create()\n        assert self.id is not None  # nosec\n        async for message in AgentThreadActions.get_messages(self._client, self.id, sort_order=sort_order):\n            yield message\n\n\n@experimental\n@register_agent_type(\"foundry_agent\")\nclass AzureAIAgent(DeclarativeSpecMixin, Agent):\n    \"\"\"Azure AI Agent class.\"\"\"\n\n    client: AIProjectClient\n    definition: AzureAIAgentModel\n    polling_options: RunPollingOptions = Field(default_factory=RunPollingOptions)\n    mcp_tool_approval_callback: MCPToolApprovalCallback | None = None\n\n    channel_type: ClassVar[type[AgentChannel]] = AzureAIChannel","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/azure_ai/azure_ai_agent.py#L325-L361","documentation":"Raised by AzureAIAgentThread.get_messages when self._is_deleted is True. After a thread is deleted it cannot serve messages, so any further read is rejected. Thrown as a plain ValueError at the start of get_messages.","triggerScenarios":"Calling get_messages() after await thread.delete() completed; iterating history in a finally/teardown block that runs after deletion; holding a stale thread reference across a session reset.","commonSituations":"Cleanup ordering bug where history retrieval and deletion race; UI/test code that lists messages after the user/session teardown deleted the thread; reusing a thread object across multiple create/delete cycles without resetting the _is_deleted flag.","solutions":["Do not call get_messages after delete; restructure teardown so reads happen before deletion.","Track thread lifecycle in your code and skip reads when the thread is known to be deleted.","Create a fresh AzureAIAgentThread for a new session instead of reusing a deleted one."],"exampleFix":"// before\nawait thread.delete()\nasync for m in thread.get_messages(): ...  // error\n// after\nasync for m in thread.get_messages(): ...\nawait thread.delete()  // reads first, then delete","handlingStrategy":"validation","validationCode":"async def safe_get_messages(thread):\n    if getattr(thread, '_is_deleted', False):\n        return []\n    return [m async for m in thread.get_messages()]","typeGuard":"def thread_is_alive(thread) -> bool:\n    return not getattr(thread, '_is_deleted', False)","tryCatchPattern":"try:\n    async for m in thread.get_messages(): ...\nexcept ValueError as e:\n    if 'has been deleted' in str(e):\n        log.warning('skipping read on deleted thread')\n    else:\n        raise","preventionTips":["Order teardown so all reads complete before delete().","Track thread liveness in your session manager and skip reads after delete.","Create a new thread per session rather than reusing a deleted one."],"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"}