microsoft/semantic-kernel · error · AgentThreadOperationException
Cannot retrieve chat history, since the thread has been dele
Error message
Cannot retrieve chat history, since the thread has been deleted.
What it means
Raised by the chat-completion AgentThread.get_messages (an AgentThreadOperationException) when self._is_deleted is true. Once the thread is deleted, the in-memory chat history is no longer accessible through this thread handle, so retrieval is blocked.
Source
Thrown at python/semantic_kernel/agents/chat_completion/chat_completion_agent.py:101
"""Called when a new message has been contributed to the chat."""
if isinstance(new_message, str):
new_message = ChatMessageContent(role=AuthorRole.USER, content=new_message)
if (
not new_message.metadata
or "thread_id" not in new_message.metadata
or new_message.metadata["thread_id"] != self._id
):
self._chat_history.add_message(new_message)
async def get_messages(self) -> AsyncIterable[ChatMessageContent]:
"""Retrieve the current chat history.
Returns:
An async iterable of ChatMessageContent.
"""
if self._is_deleted:
raise AgentThreadOperationException("Cannot retrieve chat history, since the thread has been deleted.")
if self._id is None:
await self.create()
for message in self._chat_history.messages:
yield message
async def reduce(self) -> ChatHistory | None:
"""Reduce the chat history to a smaller size."""
if self._id is None:
raise AgentThreadOperationException("Cannot reduce chat history, since the thread is not currently active.")
if not isinstance(self._chat_history, ChatHistoryReducer):
return None
return await self._chat_history.reduce()
@register_agent_type("chat_completion_agent")
class ChatCompletionAgent(DeclarativeSpecMixin, Agent):
"""A Chat Completion Agent based on ChatCompletionClientBase."""
View on GitHub (pinned to c028a0c7dc)
Solutions
- Do not call get_messages after delete; obtain a fresh thread for a new conversation.
- Track deletion state in your code and skip reads once the thread is deleted.
- Move any history inspection before the delete call.
- If you need history after deletion, persist it before deleting.
Example fix
// before await thread.delete() msgs = [m async for m in thread.get_messages()] # raises // after msgs = [m async for m in thread.get_messages()] # read first await thread.delete()
Defensive patterns
Strategy: validation
Validate before calling
if thread._is_deleted:
raise RuntimeError('Thread already deleted; cannot read messages')
msgs = [m async for m in thread.get_messages()] Type guard
def thread_is_active(thread) -> bool:
return not getattr(thread, '_is_deleted', False) Try / catch
from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException
try:
msgs = [m async for m in thread.get_messages()]
except AgentThreadOperationException as e:
if 'has been deleted' in str(e): msgs = []
else: raise Prevention
- Read history before delete
- Track deletion state in your code and skip post-delete reads
When it happens
Trigger: Calling thread.get_messages() after thread.delete() has been called on the same AgentThread instance; reusing a thread handle whose lifecycle has ended.
Common situations: Teardown then a delayed/raced read; holding a thread reference across a delete boundary; cleanup logic that deletes then a finally-block tries to log messages.
Related errors
- Cannot reduce chat history, since the thread is not currentl
- MaxTokens {maxTokens} is not valid, the value must be greate
- Invalid choice
- Invalid kernel selection. {selectedKernelName} is not a vali
- Unsupported image format.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/8b74dd3ba4d9a2ef.
Report an issue: GitHub.