jd-opensource/joyagent-jdgenie · error · ValueError

工具名称不能为空且必须是字符串类型

Error message

工具名称不能为空且必须是字符串类型

What it means

Input validation at the start of the MCP client's call_tool: the tool name must be a non-empty string because it is the key used to look up the tool on the server. A None or non-string name would fail the RPC or cause a confusing lookup error downstream, so a ValueError is raised up front; fires when callers pass an invalid tool name (e.g. an unset variable) instead of a real tool identifier.

Solutions

  1. Ensure the tool name is a non-empty string before calling call_tool
  2. If iterating a tool list, pass `tool.name`, not the tool object
  3. Validate config-sourced names after loading and fail fast with a clear message

Example fix

// before
await client.call_tool(config["tool"].id)
// after
await client.call_tool(config["tool"]["name"])
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(tool_name, str) or not tool_name:
    raise ValueError(f"Invalid tool name: {tool_name!r}")

Type guard

def is_valid_tool_name(name) -> bool:
    return isinstance(name, str) and bool(name.strip())

Try / catch

try:
    result = await client.call_tool(name, args)
except ValueError as e:
    logger.error(f"bad tool arguments: {e}")
    raise

Prevention

When it happens

Trigger: `client.call_tool(None)`, `client.call_tool("")`, or passing a non-string (int, Tool object, bytes) as the tool name.

Common situations: Tool name sourced from a config file or an upstream list where an entry is missing/empty; passing a tool object instead of its `name` field; YAML/JSON key mismatch yielding None.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08). Data as JSON: /api/errors/bd67eabe57200168. Report an issue: GitHub.

Appendix: source

Thrown at genie-client/app/client.py:313

    async def call_tool(self, name: str, arguments: Optional[Dict[str, Any]] = None) -> Any:
        """
        调用指定的工具

        Args:
            name: 工具名称
            arguments: 工具参数字典,默认为空字典

        Returns:
            Any: 工具执行结果

        Raises:
            ValueError: 当工具名称无效时抛出
            Exception: 当工具调用失败时抛出异常
        """
        # 参数验证
        if not name or not isinstance(name, str):
            raise ValueError("工具名称不能为空且必须是字符串类型")

        if arguments is None:
            arguments = {}
        elif not isinstance(arguments, dict):
            raise ValueError("工具参数必须是字典类型")

        try:
            async with self._sse_connection() as session:
                logger.info(f"正在调用工具 '{name}',参数: {arguments}")

                # 调用工具
                response = await session.call_tool(name=name, arguments=arguments)

                logger.info(f"工具 '{name}' 执行成功")
                logger.debug(f"工具 '{name}' 返回结果类型: {type(response).__name__}")

                return response

View on GitHub (pinned to 2417e0b8b6)