microsoft/semantic-kernel · error · ServiceInvalidRequestError

Multiple system messages in chat history. Only one system…

Error message

Multiple system messages in chat history. Only one system message is expected.

What it means

Raised by filter_system_message when more than one message with AuthorRole.SYSTEM exists in the ChatHistory. The Gemini API accepts a single system_instruction in the generate_content config; it does not support multiple system messages interleaved in the conversation. filter_system_message extracts the first system message for the config and rejects the presence of additional ones.

Solutions

  1. Keep exactly one system message in the ChatHistory; update its content in place instead of adding a second.
  2. Before sending, remove all but the first system message: filter and re-insert a single consolidated system message.
  3. If you need multi-part instructions, concatenate them into a single system message's text.

Example fix

# before
history.add_system_message('You are a helpful assistant.')
history.add_system_message('Always be concise.')  # second system message

# after
history.add_system_message('You are a helpful assistant. Always be concise.')
Defensive patterns

Strategy: validation

Validate before calling

from semantic_kernel.contents.utils.author_role import AuthorRole

def validate_single_system_message(chat_history):
    system_msgs = [m for m in chat_history if m.role == AuthorRole.SYSTEM]
    if len(system_msgs) > 1:
        raise ValueError(f'Found {len(system_msgs)} system messages; Google AI allows only one.')

Type guard

from semantic_kernel.contents.utils.author_role import AuthorRole

def has_at_most_one_system_message(chat_history) -> bool:
    return sum(1 for m in chat_history if m.role == AuthorRole.SYSTEM) <= 1

Prevention

When it happens

Trigger: Adding two or more messages with role=AuthorRole.SYSTEM to a ChatHistory and then calling a Google AI chat completion method (which calls filter_system_message on the history).

Common situations: Prepending a system prompt to history that already contains a system message; accumulating conversation turns across multiple calls without clearing prior system messages; merging two ChatHistory objects that each had a system message.

Related errors


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

Appendix: source

Thrown at python/semantic_kernel/connectors/ai/google/shared_utils.py:23

from typing import Any

from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceType
from semantic_kernel.const import DEFAULT_FULLY_QUALIFIED_NAME_SEPARATOR
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.contents.utils.author_role import AuthorRole
from semantic_kernel.exceptions.service_exceptions import ServiceInvalidRequestError

logger: logging.Logger = logging.getLogger(__name__)


def filter_system_message(chat_history: ChatHistory) -> str | None:
    """Filter the first system message from the chat history.

    If there are multiple system messages, raise an error.
    If there are no system messages, return None.
    """
    if len([message for message in chat_history if message.role == AuthorRole.SYSTEM]) > 1:
        raise ServiceInvalidRequestError(
            "Multiple system messages in chat history. Only one system message is expected."
        )

    for message in chat_history:
        if message.role == AuthorRole.SYSTEM:
            return message.content

    return None


FUNCTION_CHOICE_TYPE_TO_GOOGLE_FUNCTION_CALLING_MODE = {
    FunctionChoiceType.AUTO: "AUTO",
    FunctionChoiceType.NONE: "NONE",
    FunctionChoiceType.REQUIRED: "ANY",
}

# The separator used in the fully qualified name of the function instead of the default "-" separator.
# This is required since Gemini doesn't work well with "-" in the function name.

View on GitHub (pinned to c028a0c7dc)