run-llama/llama_index · error · ValueError

Cannot specify both system_prompt and prefix_messages

Error message

Cannot specify both system_prompt and prefix_messages

What it means

SimpleChatEngine.from_defaults() raises ValueError when both system_prompt and prefix_messages are passed. As with ContextChatEngine, system_prompt is a convenience that is internally expanded into a one-element prefix_messages list with the model's system role; supplying both is treated as conflicting configuration.

Source

Thrown at llama-index-core/llama_index/core/chat_engine/simple.py:58

        chat_history: Optional[List[ChatMessage]] = None,
        memory: Optional[BaseMemory] = None,
        memory_cls: Type[BaseMemory] = Memory,
        system_prompt: Optional[str] = None,
        prefix_messages: Optional[List[ChatMessage]] = None,
        llm: Optional[LLM] = None,
        **kwargs: Any,
    ) -> "SimpleChatEngine":
        """Initialize a SimpleChatEngine from default parameters."""
        llm = llm or Settings.llm

        chat_history = chat_history or []
        memory = memory or memory_cls.from_defaults(
            chat_history=chat_history, token_limit=llm.metadata.context_window - 256
        )

        if system_prompt is not None:
            if prefix_messages is not None:
                raise ValueError(
                    "Cannot specify both system_prompt and prefix_messages"
                )
            prefix_messages = [
                ChatMessage(content=system_prompt, role=llm.metadata.system_role)
            ]

        prefix_messages = prefix_messages or []

        return cls(
            llm=llm,
            memory=memory,
            prefix_messages=prefix_messages,
            callback_manager=Settings.callback_manager,
        )

    @trace_method("chat")
    def chat(
        self, message: str, chat_history: Optional[List[ChatMessage]] = None

View on GitHub (pinned to afd0fef371)

Solutions

  1. Pass exactly one of system_prompt or prefix_messages
  2. Merge the system message into prefix_messages using role=llm.metadata.system_role if multiple leading messages are needed
  3. Strip empty-string system_prompt values before calling from_defaults (an empty string is still not None and triggers the check)

Example fix

# before
engine = SimpleChatEngine.from_defaults(
    system_prompt='You are terse.',
    prefix_messages=[ChatMessage(role='system', content='Answer in bullet points')],
)  # ValueError

# after
from llama_index.core.llms import ChatMessage, MessageRole
engine = SimpleChatEngine.from_defaults(
    prefix_messages=[ChatMessage(role=MessageRole.SYSTEM, content='You are terse. Answer in bullet points.')],
)
Defensive patterns

Strategy: validation

Validate before calling

assert not (system_prompt and prefix_messages), 'Pass only one of system_prompt or prefix_messages to SimpleChatEngine'

Try / catch

try:
    engine = SimpleChatEngine.from_defaults(system_prompt=sp, prefix_messages=pm)
except ValueError as e:
    if 'Cannot specify both' in str(e):
        engine = SimpleChatEngine.from_defaults(prefix_messages=pm or None)
    else:
        raise

Prevention

When it happens

Trigger: SimpleChatEngine.from_defaults(system_prompt='...', prefix_messages=[...]) — the guard inside the system_prompt branch fires. Common when a generic config dict is splatted into from_defaults.

Common situations: Wrapper code that accepts both options for API compatibility and forwards them verbatim; refactoring from prefix_messages to system_prompt without removing the old kwarg; YAML/JSON configs carrying legacy fields.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/f499e02bd2906a4c. Report an issue: GitHub.