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 as AgentThreadOperationException by AssistantAgentThread._delete when the underlying client.beta.threads.delete() call throws. The original service exception is chained (from ex), preserving the real cause (auth, not-found, network, rate limit).

Source

Thrown at python/semantic_kernel/agents/open_ai/openai_assistant_agent.py:190

                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.beta.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)

        # Only add the message to the thread if it's not already there
        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 AssistantThreadActions.create_message(self._client, self._id, new_message)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inspect the chained __cause__ for the actual status (404 = already gone, 401/403 = auth, 429 = rate limit).
  2. Treat 404 as benign in cleanup (the thread is already deleted).
  3. Retry with backoff for 429/5xx; refresh credentials for 401/403.
  4. Avoid double-deleting; track deletion state.

Example fix

# before
try:
    await thread.delete()
except AgentThreadOperationException:
    pass  # swallows real cause
# after
try:
    await thread.delete()
except AgentThreadOperationException as e:
    cause = e.__cause__
    if getattr(cause, "status_code", None) == 404:
        logging.info("thread already deleted")
    else:
        raise
Defensive patterns

Strategy: try-catch

Try / catch

import asyncio
from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException

async def safe_delete(thread, attempts=3):
    for i in range(attempts):
        try:
            return await thread.delete()
        except AgentThreadOperationException as e:
            cause = e.__cause__
            status = getattr(cause, "status_code", None)
            if status == 404:
                logging.info("thread already deleted")
                return
            if status in (429, 500, 502, 503) and i < attempts - 1:
                await asyncio.sleep(2 ** i)
                continue
            raise

Prevention

When it happens

Trigger: Calling thread.delete() (valid id present) when the OpenAI service rejects the delete: the thread id no longer exists, credentials are invalid/expired, rate limited, or a network error occurs.

Common situations: Deleting a thread that was already deleted; expired token; race condition where the thread was removed elsewhere; transient network failures.

Related errors


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