{"record":{"id":"859b8ab293e2ebcc","repo":"run-llama/llama_index","slug":"at-least-one-agent-must-be-provided","errorCode":null,"errorMessage":"At least one agent must be provided","messagePattern":"At least one agent must be provided","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py","lineNumber":121,"sourceCode":"        self,\n        agents: List[BaseWorkflowAgent],\n        initial_state: Optional[Dict] = None,\n        root_agent: Optional[str] = None,\n        handoff_prompt: Optional[Union[str, BasePromptTemplate]] = None,\n        handoff_output_prompt: Optional[Union[str, BasePromptTemplate]] = None,\n        state_prompt: Optional[Union[str, BasePromptTemplate]] = None,\n        timeout: Optional[float] = None,\n        output_cls: Optional[Type[BaseModel]] = None,\n        structured_output_fn: Optional[\n            Callable[[List[ChatMessage]], Dict[str, Any]]\n        ] = None,\n        early_stopping_method: Literal[\"force\", \"generate\"] = \"force\",\n        **workflow_kwargs: Any,\n    ):\n        super().__init__(timeout=timeout, **workflow_kwargs)\n        self.early_stopping_method = early_stopping_method\n        if not agents:\n            raise ValueError(\"At least one agent must be provided\")\n\n        # Raise an error if any agent has no name or no description\n        if len(agents) > 1 and any(\n            agent.name == DEFAULT_AGENT_NAME for agent in agents\n        ):\n            raise ValueError(\"All agents must have a name in a multi-agent workflow\")\n\n        if len(agents) > 1 and any(\n            agent.description == DEFAULT_AGENT_DESCRIPTION for agent in agents\n        ):\n            raise ValueError(\n                \"All agents must have a description in a multi-agent workflow\"\n            )\n\n        if any(agent.initial_state for agent in agents):\n            raise ValueError(\n                \"Initial state is not supported per-agent in AgentWorkflow\"\n            )","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py#L103-L139","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nout = await retriever_tool.acall()  # ValueError: Cannot call query engine without inputs\n\n# after\nargs = json.loads(tool_call.function.arguments)\nif not (args.get(\"input\") or \"\").strip():\n    args[\"input\"] = fallback_query\nout = await retriever_tool.acall(**args)","handlingStrategy":"validation","validationCode":"if not args and not kwargs:\n    kwargs['input'] = clarifying_query  # or raise your own error\nout = await tool.acall(*args, **kwargs)","typeGuard":"def has_tool_input(args: tuple, kwargs: dict) -> bool:\n    return len(args) > 0 or len(kwargs) > 0","tryCatchPattern":"try:\n    out = await tool.acall(*args, **kwargs)\nexcept ValueError as e:\n    if 'without inputs' in str(e):\n        out = await tool.acall(input=clarified_query)\n    else:\n        raise","preventionTips":["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."],"tags":["tools","retriever","async","empty-input"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}