datawhalechina/hello-agents · error · WorkflowExecutionError

失败:工具 未注册

Error message

{stage}失败:工具 {name} 未注册

What it means

Raised by _run_tool (src/workflow.py:145) when tool_registry.get_tool(name) returns None for the tool an agent tried to invoke. The registry is the official ToolRegistry, and only tools registered at workflow construction are resolvable — the error names the missing tool so you can see exactly which one the model asked for.

Solutions

  1. Compare the name in the error against the names passed to ToolRegistry at setup; register the missing tool or fix the name mismatch.
  2. Regenerate/refresh tool descriptions given to the model so the advertised list matches the registry.
  3. If the tool was intentionally removed, also remove it from the agent's tool schema/prompt to stop the model from calling it.

Example fix

# before
registry = ToolRegistry()
registry.register(SearchTool(name="web_lookup"))

# after (match what the model calls)
registry = ToolRegistry()
registry.register(SearchTool(name="search"))
Defensive patterns

Strategy: validation

Validate before calling

# keep the advertised tool list and the registry in lockstep
registered = set(tool_registry.list_tools()) if hasattr(tool_registry, "list_tools") else set()
advertised = {t.name for t in tool_schemas_given_to_model}
assert advertised <= registered, f"prompt advertises unregistered tools: {advertised - registered}"

Type guard

def tool_is_registered(registry, name: str) -> bool:
    return registry.get_tool(name) is not None

assert tool_is_registered(tool_registry, "search")

Try / catch

try:
    result = workflow.run(requirement)
except WorkflowExecutionError as e:
    if "未注册" in str(e):
        # register the missing tool and retry, or drop it from the prompt
        fix_tool_registry()
        result = workflow.run(requirement)
    else:
        raise

Prevention

When it happens

Trigger: The LLM emits a tool call with a name that was never registered (hallucinated or renamed tool); the tool set was trimmed between versions; a tool registered under a different key than the schema the model was told about.

Common situations: Prompt/schema drift: the tool description sent to the model lists an old tool name; a tool class renamed without updating prompts; selectively disabling tools for cost while the prompt still advertises them.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/d19b1711fa35d1d8. Report an issue: GitHub.

Appendix: source

Thrown at Co-creation-projects/zenith191-RequirementClarifierAgent/src/workflow.py:145

    @staticmethod
    def _run_agent(stage: str, agent: AgentLike, prompt: str) -> str:
        try:
            response = agent.run(prompt)
        except Exception as exc:
            raise WorkflowExecutionError(f"{stage}阶段执行失败:{exc}") from exc
        if not isinstance(response, str) or not response.strip():
            raise WorkflowExecutionError(f"{stage}阶段返回了空结果")
        return response.strip()

    def _run_tool(
        self, name: str, parameters: dict[str, object], stage: str
    ) -> dict[str, object]:
        """通过官方 ToolRegistry 获取工具并解析其字符串协议。"""

        tool = self.tool_registry.get_tool(name)
        if tool is None:
            raise WorkflowExecutionError(f"{stage}失败:工具 {name} 未注册")
        try:
            raw_result = tool.run(parameters)
        except Exception as exc:
            raise WorkflowExecutionError(f"{stage}失败:工具执行异常:{exc}") from exc
        try:
            payload = json.loads(raw_result)
        except (TypeError, ValueError) as exc:
            raise WorkflowExecutionError(f"{stage}失败:工具返回的不是有效 JSON") from exc
        if not isinstance(payload, dict):
            raise WorkflowExecutionError(f"{stage}失败:工具结果必须是 JSON 对象")
        if not payload.get("ok"):
            raise WorkflowExecutionError(
                f"{stage}失败:{payload.get('message', '未知工具错误')}"
            )
        return payload

    def _clear_agent_histories(self) -> None:
        """避免多次运行时把上一条需求带入下一条需求。"""

View on GitHub (pinned to 606a07d341)