run-llama/llama_index · error · ValueError

At least one agent must be provided

Error message

At least one agent must be provided

What it means

RetrieverTool.acall mirrors the sync path: it assembles a query from args and kwargs and raises ValueError when the assembled string is empty, before awaiting retriever.aretrieve. Hitting it means the async tool invocation carried no usable input.

Source

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

        self,
        agents: List[BaseWorkflowAgent],
        initial_state: Optional[Dict] = None,
        root_agent: Optional[str] = None,
        handoff_prompt: Optional[Union[str, BasePromptTemplate]] = None,
        handoff_output_prompt: Optional[Union[str, BasePromptTemplate]] = None,
        state_prompt: Optional[Union[str, BasePromptTemplate]] = None,
        timeout: Optional[float] = None,
        output_cls: Optional[Type[BaseModel]] = None,
        structured_output_fn: Optional[
            Callable[[List[ChatMessage]], Dict[str, Any]]
        ] = None,
        early_stopping_method: Literal["force", "generate"] = "force",
        **workflow_kwargs: Any,
    ):
        super().__init__(timeout=timeout, **workflow_kwargs)
        self.early_stopping_method = early_stopping_method
        if not agents:
            raise ValueError("At least one agent must be provided")

        # Raise an error if any agent has no name or no description
        if len(agents) > 1 and any(
            agent.name == DEFAULT_AGENT_NAME for agent in agents
        ):
            raise ValueError("All agents must have a name in a multi-agent workflow")

        if len(agents) > 1 and any(
            agent.description == DEFAULT_AGENT_DESCRIPTION for agent in agents
        ):
            raise ValueError(
                "All agents must have a description in a multi-agent workflow"
            )

        if any(agent.initial_state for agent in agents):
            raise ValueError(
                "Initial state is not supported per-agent in AgentWorkflow"
            )

View on GitHub (pinned to afd0fef371)

Solutions

  1. Provide input: await tool.acall('question') or await tool.acall(input='question').
  2. Pre-validate the LLM tool-call payload: parse arguments JSON, require a non-empty query, else re-request from the model.
  3. Make the query field required in the tool's fn_schema/ToolMetadata.
  4. Wrap dispatch in try/except ValueError and log + retry with a corrective prompt.

Example fix

# before
out = await retriever_tool.acall()  # ValueError: Cannot call query engine without inputs

# after
args = json.loads(tool_call.function.arguments)
if not (args.get("input") or "").strip():
    args["input"] = fallback_query
out = await retriever_tool.acall(**args)
Defensive patterns

Strategy: validation

Validate before calling

if not args and not kwargs:
    kwargs['input'] = clarifying_query  # or raise your own error
out = await tool.acall(*args, **kwargs)

Type guard

def has_tool_input(args: tuple, kwargs: dict) -> bool:
    return len(args) > 0 or len(kwargs) > 0

Try / catch

try:
    out = await tool.acall(*args, **kwargs)
except ValueError as e:
    if 'without inputs' in str(e):
        out = await tool.acall(input=clarified_query)
    else:
        raise

Prevention

When it happens

Trigger: Awaiting tool.acall() with zero arguments; an async agent loop forwarding an empty arguments dict from the LLM's tool call; routers that dispatch tools by name only, dropping the payload.

Common situations: Async agent frameworks (custom OpenAI-function loops) where tool-call arguments failed to parse; streaming pipelines that emit tool calls before arguments arrive; permissive fn_schema allowing omitted queries.

Related errors


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