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.
Solutions
- Provide input: await tool.acall('question') or await tool.acall(input='question').
- Pre-validate the LLM tool-call payload: parse arguments JSON, require a non-empty query, else re-request from the model.
- Make the query field required in the tool's fn_schema/ToolMetadata.
- 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
- Parse and validate LLM tool-call arguments JSON before async dispatch.
- Require the query field in the tool schema.
- Log empty-argument tool calls and re-prompt the model.
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
- LLM must be a FunctionCallingLLM
- llm must be a function calling LLM to use handoff
- Aborting parsing document;
- achat_stream is None!
- achat_stream is None. Cannot asynchronously write to…
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/859b8ab293e2ebcc.
Report an issue: GitHub.
Appendix: 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)