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
- Keep exactly one system message in the ChatHistory; update its content in place instead of adding a second.
- Before sending, remove all but the first system message: filter and re-insert a single consolidated system message.
- 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
- Maintain a single system message; update its content in place rather than appending another.
- Consolidate multi-part instructions into one system message string.
- Before each Google AI request, assert at most one system message exists in history.
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
- Chat history can't contain only system messages.
- Chat history must contain at least one message
- Failed to validate Google AI settings
- Failed to validate Google AI settings
- ImageContent without data_uri in User message while…
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)