microsoft/semantic-kernel · error · ServiceInvalidRequestError
System messages are not supported in Gemma
Error message
System messages are not supported in Gemma
What it means
Google's Gemma models do not support system-role messages in their prompt format. The gemma_template() function explicitly checks every message's role and raises ServiceInvalidRequestError (an HTTP-400-equivalent client error) if any message has AuthorRole.SYSTEM. This is a hard API contract from the model, not a library limitation.
Source
Thrown at python/semantic_kernel/connectors/ai/onnx/utils.py:167
return phi4mm_input
def gemma_template(history: ChatHistory) -> str:
"""Generates a formatted string for the Gemma model based on the provided chat history.
Args:
history (ChatHistory): An object containing the chat history with messages.
Returns:
str: A formatted string representing the chat history for the Gemma model.
Raises:
ServiceInvalidRequestError: If a system message is encountered in the chat history.
"""
gemma_input = "<bos>"
for message in history.messages:
if message.role == AuthorRole.SYSTEM:
raise ServiceInvalidRequestError("System messages are not supported in Gemma")
if message.role == AuthorRole.USER:
gemma_input += f"<start_of_turn>user\n{message.content}<end_of_turn>\n"
if message.role == AuthorRole.ASSISTANT:
gemma_input += f"<start_of_turn>model\n{message.content}<end_of_turn>\n"
gemma_input += "<start_of_turn>model\n"
return gemma_input
def llama_template(history: ChatHistory) -> str:
"""Generates a formatted string from a given chat history for use with the LLaMA model.
Args:
history (ChatHistory): An object containing the chat history, which includes a list of messages.
Returns:
str: A formatted string where each message is wrapped with specific header and end tags,
and the final string ends with an assistant header tag.
"""View on GitHub (pinned to c028a0c7dc)
Solutions
- Remove or convert the system message to a user message before calling the Gemma service: merge the system instruction into the first user turn.
- Filter system messages from ChatHistory right before the call: history.messages = [m for m in history.messages if m.role != AuthorRole.SYSTEM].
- Use a different template/model (e.g. ONNXTemplate.PHI3) if you need native system-role support.
- Guard at the application layer with a template-aware check so system messages are never sent to Gemma.
Example fix
// before
history.add_system_message("You are a helpful assistant.")
result = gemma_service.get_chat_message_contents(history=history)
// after
system_msg = next((m for m in history.messages if m.role == AuthorRole.SYSTEM), None)
if system_msg:
history.remove_message(system_msg)
history.messages.insert(0, ChatMessageContent(role=AuthorRole.USER, content=system_msg.content))
result = gemma_service.get_chat_message_contents(history=history) Defensive patterns
Strategy: validation
Validate before calling
from semantic_kernel.contents import AuthorRole
def strip_system_messages_for_gemma(history):
"""Remove system messages before sending to Gemma — merge into first user turn."""
system_msgs = [m for m in history.messages if m.role == AuthorRole.SYSTEM]
if system_msgs:
history.messages = [m for m in history.messages if m.role != AuthorRole.SYSTEM]
merged = ' '.join(m.content for m in system_msgs)
if history.messages and history.messages[0].role == AuthorRole.USER:
history.messages[0].content = merged + '\n' + history.messages[0].content
return history Type guard
def is_gemma_compatible(history) -> bool:
return all(m.role != AuthorRole.SYSTEM for m in history.messages) Try / catch
from semantic_kernel.exceptions import ServiceInvalidRequestError
try:
result = gemma_service.get_chat_message_contents(history=history)
except ServiceInvalidRequestError as e:
if 'System messages' in str(e):
history = strip_system_messages_for_gemma(history)
result = gemma_service.get_chat_message_contents(history=history) Prevention
- Never add system-role messages to a ChatHistory destined for a Gemma model.
- Build a model-aware pipeline that checks the target template before constructing history.
- If you need system instructions for Gemma, embed them in the first user message.
When it happens
Trigger: Calling an ONNX Gemma chat completion with a ChatHistory that contains at least one message where role == AuthorRole.SYSTEM — typically from adding a system prompt via history.add_system_message() or a kernel function that auto-injects one.
Common situations: Using the same ChatHistory builder across models (a system prompt that works for GPT/Phi fails for Gemma); templated pipelines that always prepend a system instruction; copying examples designed for OpenAI models into a Gemma workflow.
Related errors
- An error occurred while applying the template: {template.val
- Chat history can't contain only system messages.
- Cannot reduce chat history, since the thread is not currentl
- Multiple system messages in chat history. Only one system me
- Configuration not found, please setup the notebooks first us
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/b8d1e78bf1aab3a4.
Report an issue: GitHub.