run-llama/llama_index · error · ValueError

State prompt must contain {state} and {msg}

Error message

State prompt must contain {state} and {msg}

What it means

state_prompt controls how the current workflow state and the incoming user message are rendered into the agent's system context. When given as a string, it must contain both '{state}' and '{msg}' placeholders or AgentWorkflow raises, since the runtime substitutes both values on every run.

Source

Thrown at llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py:181

        if isinstance(handoff_output_prompt, str):
            handoff_output_prompt = PromptTemplate(handoff_output_prompt)
            if (
                "{to_agent}" not in handoff_output_prompt.get_template()
                or "{reason}" not in handoff_output_prompt.get_template()
            ):
                raise ValueError(
                    "Handoff output prompt must contain {to_agent} and {reason}"
                )
        self.handoff_output_prompt = handoff_output_prompt

        state_prompt = state_prompt or DEFAULT_STATE_PROMPT
        if isinstance(state_prompt, str):
            state_prompt = PromptTemplate(state_prompt)
            if (
                "{state}" not in state_prompt.get_template()
                or "{msg}" not in state_prompt.get_template()
            ):
                raise ValueError("State prompt must contain {state} and {msg}")
        self.state_prompt = state_prompt

        self.output_cls = output_cls
        self.structured_output_fn = structured_output_fn
        if output_cls is not None and structured_output_fn is not None:
            self.structured_output_fn = None

    def _get_prompts(self) -> PromptDictType:
        """Get prompts."""
        return {
            "handoff_prompt": self.handoff_prompt,
            "handoff_output_prompt": self.handoff_output_prompt,
            "state_prompt": self.state_prompt,
        }

    def _get_prompt_modules(self) -> PromptMixinType:
        """Get prompt sub-modules."""
        return {agent.name: agent for agent in self.agents.values()}

View on GitHub (pinned to afd0fef371)

Solutions

  1. Include both tokens, e.g. state_prompt="Current state:\n{state}\nUser message: {msg}".
  2. Or omit state_prompt to use DEFAULT_STATE_PROMPT.
  3. If you want to exclude state content, keep the placeholders and supply an empty/filtered state rather than deleting tokens.

Example fix

# before
wf = AgentWorkflow(agents=[...], root_agent="researcher", state_prompt="State: {state}")  # ValueError

# after
wf = AgentWorkflow(
    agents=[...], root_agent="researcher",
    state_prompt="State: {state}\nMessage: {msg}",
)
Defensive patterns

Strategy: validation

Validate before calling

def check_state_prompt(tpl: str):
    for token in ("{state}", "{msg}"):
        if token not in tpl:
            raise ValueError(f"state_prompt must contain {token}")
    return tpl

Prevention

When it happens

Trigger: AgentWorkflow(..., state_prompt=...) with a string template missing '{state}' or '{msg}'. Note the object stored is a PromptTemplate; only string inputs pass through this validation.

Common situations: Customizing state prompts to hide state from the LLM; adapting examples where only one placeholder was used; version changes that added the {msg} requirement.

Related errors


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