run-llama/llama_index · error · ValueError

Must provide either user_msg or chat_history

Error message

Must provide either user_msg or chat_history

What it means

AgentWorkflow's init step requires input: user_msg (str or List[ChatMessage]) or a chat_history (List[ChatMessage]). If neither is passed to .run()/.astream(), there is no user turn to process and the workflow raises before any agent runs.

Source

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

            )
            await ctx.store.set("user_msg_str", content_str)
        elif chat_history and not all(
            message.role == "system" for message in chat_history
        ):
            # If no user message, use the last message from chat history as user_msg_str
            user_hist: List[ChatMessage] = [
                msg for msg in chat_history if msg.role == "user"
            ]
            content_str = "\n".join(
                [
                    block.text
                    for block in user_hist[-1].blocks
                    if isinstance(block, TextBlock)
                ]
            )
            await ctx.store.set("user_msg_str", content_str)
        else:
            raise ValueError("Must provide either user_msg or chat_history")

        # Get all messages from memory
        input_messages = await memory.aget()

        # send to the current agent
        current_agent_name: str = await ctx.store.get("current_agent_name")
        return AgentInput(input=input_messages, current_agent_name=current_agent_name)

    @step
    async def setup_agent(self, ctx: Context, ev: AgentInput) -> AgentSetup:
        """Main agent handling logic."""
        current_agent_name = ev.current_agent_name
        agent = self.agents[current_agent_name]
        llm_input = [*ev.input]

        if agent.system_prompt:
            llm_input = [
                ChatMessage(role="system", content=agent.system_prompt),

View on GitHub (pinned to afd0fef371)

Solutions

  1. Pass a message: `await wf.run(user_msg="Summarize this", memory=memory)`.
  2. Or pass chat_history=[ChatMessage(role="user", content="...")] together with memory.
  3. If resuming a conversation from memory, still supply at least the new user turn via user_msg.

Example fix

# before
resp = await wf.run(memory=memory)  # ValueError

# after
resp = await wf.run(user_msg="What did we discuss?", memory=memory)
Defensive patterns

Strategy: validation

Validate before calling

def validate_run_input(user_msg=None, chat_history=None):
    if not user_msg and not chat_history:
        raise ValueError("AgentWorkflow.run requires user_msg or non-empty chat_history")

Type guard

def has_run_input(user_msg, chat_history) -> bool:
    return bool(user_msg) or bool(chat_history)

Prevention

When it happens

Trigger: Calling `await wf.run()` with no arguments; passing only memory= (ChatMemoryBuffer) without chat_history; passing an empty chat_history list — an empty list is falsy and falls into the same else branch.

Common situations: Expecting AgentWorkflow to continue from memory alone (memory is loaded after this check, but the input check comes first); refactoring run() calls and dropping the message argument; passing an empty list after filtering chat history.

Related errors


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