microsoft/semantic-kernel · error · AgentChatException

System messages cannot be added to the chat history.

Error message

System messages cannot be added to the chat history.

What it means

Raised by AgentChat.add_chat_messages() (and transitively add_chat_message()) when any message in the batch has role == AuthorRole.SYSTEM. The group-chat history is designed to hold user/assistant/tool messages only; system messages are rejected because they represent instructions that should be configured at the agent level, not injected into shared chat history. It is an AgentChatException.

Solutions

  1. Filter out SYSTEM-role messages before calling add_chat_messages/add_chat_message.
  2. Set system-level instructions on the individual agent's instructions or prompt_template_config instead of injecting them into the shared history.
  3. Convert system messages to user-role messages if they must appear in the history.

Example fix

# before
await chat.add_chat_message(
    ChatMessageContent(role=AuthorRole.SYSTEM, content="You are helpful")
)  # raises

# after — set instructions on the agent, add only user/assistant messages
agent = ChatCompletionAgent(instructions="You are helpful", ...)
await chat.add_chat_message(
    ChatMessageContent(role=AuthorRole.USER, content="Hello")
)
Defensive patterns

Strategy: validation

Validate before calling

from semantic_kernel.contents.utils.author_role import AuthorRole

filtered = [m for m in messages if m.role != AuthorRole.SYSTEM]
await chat.add_chat_messages(filtered)

Type guard

from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.contents.utils.author_role import AuthorRole

def has_no_system_messages(msgs: list[ChatMessageContent]) -> bool:
    return all(m.role != AuthorRole.SYSTEM for m in msgs)

Try / catch

from semantic_kernel.exceptions.agent_exceptions import AgentChatException

try:
    await chat.add_chat_messages(messages)
except AgentChatException as exc:
    if "System messages" in str(exc):
        messages = [m for m in messages if m.role != AuthorRole.SYSTEM]
        await chat.add_chat_messages(messages)
    raise

Prevention

When it happens

Trigger: Calling chat.add_chat_message(ChatMessageContent(role=AuthorRole.SYSTEM, content=...)) or add_chat_messages with a list containing a SYSTEM-role message.

Common situations: Porting code from ChatHistory (which does accept system messages) to AgentGroupChat; building messages generically and not filtering by role; accidentally including the system prompt in the message batch fed to the group chat.

Related errors


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

Appendix: source

Thrown at python/semantic_kernel/agents/group_chat/agent_chat.py:115

        return hash_value

    async def add_chat_message(self, message: str | ChatMessageContent) -> None:
        """Add a chat message."""
        if isinstance(message, str):
            message = ChatMessageContent(role=AuthorRole.USER, content=message)

        await self.add_chat_messages([message])

    async def add_chat_messages(self, messages: list[ChatMessageContent]) -> None:
        """Add chat messages."""
        self.set_activity_or_throw()

        for message in messages:
            if message.role == AuthorRole.SYSTEM:
                error_message = "System messages cannot be added to the chat history."
                logger.error(error_message)
                raise AgentChatException(error_message)

        logger.info(f"Adding `{len(messages)}` agent chat messages")

        try:
            self.history.messages.extend(messages)

            # Broadcast message to other channels (in parallel)
            # Note: Able to queue messages without synchronizing channels.
            channel_refs = [ChannelReference(channel=channel, hash=key) for key, channel in self.agent_channels.items()]
            await self.broadcast_queue.enqueue(channel_refs, messages)
        finally:
            self.clear_activity_signal()

    async def _get_or_create_channel(self, agent: Agent) -> AgentChannel:
        """Get or create a channel."""
        channel_key = self._get_agent_hash(agent)
        channel = await self._synchronize_channel(channel_key)
        if channel is None:

View on GitHub (pinned to c028a0c7dc)