run-llama/llama_index · error · ValueError
Handoff output prompt must contain {to_agent} and {reason}
Error message
Handoff output prompt must contain {to_agent} and {reason} What it means
handoff_output_prompt defines the exact string format the LLM must emit to perform a handoff (containing {to_agent} and {reason}). When passed as a string, AgentWorkflow validates both placeholders exist before wrapping it in a PromptTemplate, because _initialize_agent handoff parsing depends on this exact output shape.
Source
Thrown at llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py:169
self.root_agent = root_agent
self.initial_state = initial_state or {}
handoff_prompt = handoff_prompt or DEFAULT_HANDOFF_PROMPT
if isinstance(handoff_prompt, str):
handoff_prompt = PromptTemplate(handoff_prompt)
if "{agent_info}" not in handoff_prompt.get_template():
raise ValueError("Handoff prompt must contain {agent_info}")
self.handoff_prompt = handoff_prompt
handoff_output_prompt = handoff_output_prompt or DEFAULT_HANDOFF_OUTPUT_PROMPT
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 = NoneView on GitHub (pinned to afd0fef371)
Solutions
- Include both tokens verbatim, e.g. handoff_output_prompt='Handoff to <{to_agent}> because {reason}'.
- Or leave handoff_output_prompt unset to use DEFAULT_HANDOFF_OUTPUT_PROMPT.
- If you need a different format, keep the placeholders and only change surrounding text.
Example fix
# before
wf = AgentWorkflow(
agents=[...], root_agent="researcher",
handoff_output_prompt="Transfer to {target} since {reason}", # ValueError
)
# after
wf = AgentWorkflow(
agents=[...], root_agent="researcher",
handoff_output_prompt="Transfer to {to_agent} because {reason}",
) Defensive patterns
Strategy: validation
Validate before calling
def check_handoff_output_prompt(tpl: str):
for token in ("{to_agent}", "{reason}"):
if token not in tpl:
raise ValueError(f"handoff_output_prompt must contain {token}")
return tpl Prevention
- Never rename the {to_agent}/{reason} tokens — the handoff parser matches them.
- Change only literal wording around placeholders when customizing.
- Unit-test custom templates for placeholder presence.
When it happens
Trigger: AgentWorkflow(..., handoff_output_prompt=...) with a string template lacking either '{to_agent}' or '{reason}'. Both must be present; missing either one triggers the error.
Common situations: Reformatting the handoff output template (e.g. renaming {to_agent} to {target}) which breaks the parser; translating/localizing the prompt and losing a placeholder; copying examples from incompatible versions.
Related errors
- Handoff prompt must contain {agent_info}
- State prompt must contain {state} and {msg}
- All agents must have a name in a multi-agent workflow
- All agents must have a description in a multi-agent workflow
- Initial state is not supported per-agent in AgentWorkflow
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/94fab9154768607d.
Report an issue: GitHub.