microsoft/semantic-kernel · error · AgentThreadOperationException

The thread could not be deleted due to an error response fro

Error message

The thread could not be deleted due to an error response from the service.

What it means

Raised by AzureAIAgentThread._delete when client.agents.threads.delete raises any exception. The original service error is chained. Commonly the thread was already deleted server-side, or there is an auth/network problem. Surfaced as AgentThreadOperationException.

Source

Thrown at python/semantic_kernel/agents/azure_ai/azure_ai_agent.py:315

                messages=self._messages,
                metadata=self._metadata,
                tool_resources=self._tool_resources,
            )
        except Exception as ex:
            raise AgentThreadOperationException(
                "The thread could not be created due to an error response from the service."
            ) from ex
        return response.id

    @override
    async def _delete(self) -> None:
        """Ends the current thread."""
        if self._id is None:
            raise AgentThreadOperationException("The thread cannot be deleted because it has not been created yet.")
        try:
            await self._client.agents.threads.delete(self._id)
        except Exception as ex:
            raise AgentThreadOperationException(
                "The thread could not be deleted due to an error response from the service."
            ) from ex

    @override
    async def _on_new_message(self, new_message: str | ChatMessageContent) -> None:
        """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
        ):
            assert self.id is not None  # nosec
            await AgentThreadActions.create_message(self._client, self.id, new_message)

    async def get_messages(self, sort_order: Literal["asc", "desc"] = "desc") -> AsyncIterable[ChatMessageContent]:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inspect the chained cause to distinguish 'not found' (treat as success) from real failures.
  2. Make deletion idempotent: swallow 'not found'/404 errors and treat the thread as deleted.
  3. Retry transient 5xx/network errors with backoff; do not retry 403/404.
  4. Avoid deleting the same thread_id from multiple processes without coordination.

Example fix

try:
    await thread.delete()
except AgentThreadOperationException as e:
    if _is_not_found(e.__cause__):
        pass  # already gone, treat as success
    else:
        raise
Defensive patterns

Strategy: try-catch

Try / catch

try:
    await thread.delete()
except AgentThreadOperationException as e:
    cause = e.__cause__
    if _is_not_found(cause):
        return  # already deleted -> success
    if _is_transient(cause):
        await asyncio.sleep(backoff); await thread.delete()
    else:
        raise

Prevention

When it happens

Trigger: Deleting a thread that no longer exists (already deleted, or expired); insufficient permissions on the project; network failure; the thread_id refers to a thread in a different project/endpoint; concurrent deletion by another process.

Common situations: Cleanup code running twice (idempotency issue); a thread deleted out-of-band (portal/CLI) while the app held a reference; credential rotated between create and delete; transient 5xx.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/0b9d8cd3309b6c0b. Report an issue: GitHub.