{"record":{"id":"0cff0836c1c303d2","repo":"agentscope-ai/agentscope","slug":"enable-tools-should-be-a-list-of-strings-but-got","errorCode":null,"errorMessage":"Enable tools should be a list of strings, but got {self.enable_tools}.","messagePattern":"Enable tools should be a list of strings, but got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/mcp/_mcp_client.py","lineNumber":140,"sourceCode":"        if not re.fullmatch(r\"[a-zA-Z0-9_-]+\", self.name):\n            raise ValueError(\n                f\"MCPClient name '{self.name}' contains characters not \"\n                f\"allowed by LLM providers (only [a-zA-Z0-9_-] are \"\n                f\"permitted). Please rename it.\",\n            )\n\n        # STDIO MCP must be stateful\n        if self.mcp_config.type == \"stdio_mcp\" and not self.is_stateful:\n            raise ValueError(\n                \"STDIO MCP must be stateful (is_stateful=True).\",\n            )\n\n        # Check arguments for self.enable_tools and disable_tools\n        if self.enable_tools is not None:\n            if not isinstance(self.enable_tools, list) or any(\n                not isinstance(_, str) for _ in self.enable_tools\n            ):\n                raise ValueError(\n                    \"Enable tools should be a list of strings, but got \"\n                    f\"{self.enable_tools}.\",\n                )\n\n        if self.disable_tools is not None:\n            if not isinstance(self.disable_tools, list) or any(\n                not isinstance(_, str) for _ in self.disable_tools\n            ):\n                raise ValueError(\n                    \"Disable tools should be a list of strings, but got \"\n                    f\"{self.disable_tools}.\",\n                )\n\n        if self.enable_tools is not None and self.disable_tools is not None:\n            intersection = set(self.enable_tools).intersection(\n                set(self.disable_tools),\n            )\n            if len(intersection) != 0:","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/mcp/_mcp_client.py#L122-L158","documentation":"MCPClient validates that enable_tools, when provided, is a list of strings (tool names). Passing a single string, a set, a tuple, None-like values, or a list containing non-strings raises this ValueError at construction time.","triggerScenarios":"MCPClient(..., enable_tools=\"search\") (bare string instead of list), enable_tools={\"search\"} (set), or enable_tools=[\"search\", 3] (mixed types).","commonSituations":"Passing a single tool name as a convenience string; deserializing tool filters from JSON/YAML where a scalar or non-list sneaks in; refactoring from a tuple to a list API.","solutions":["Wrap the value in a list: enable_tools=[\"search\"]","Ensure every element is a str; convert non-strings explicitly before passing","Validate config-derived values before constructing MCPClient"],"exampleFix":"// before\nclient = MCPClient(name=\"db\", mcp_config=cfg, enable_tools=\"query\")\n\n// after\nclient = MCPClient(name=\"db\", mcp_config=cfg, enable_tools=[\"query\"])","handlingStrategy":"validation","validationCode":"enable_tools = None if enable_tools is None else [str(t) for t in enable_tools]\nassert isinstance(enable_tools, list)\nclient = MCPClient(name=n, mcp_config=cfg, enable_tools=enable_tools)","typeGuard":"def is_tool_name_list(v) -> bool:\n    return v is None or (isinstance(v, list) and all(isinstance(x, str) for x in v))","tryCatchPattern":"try:\n    MCPClient(name=n, mcp_config=cfg, enable_tools=enable_tools)\nexcept ValueError:\n    enable_tools = list(map(str, enable_tools or [])) or None\n    client = MCPClient(name=n, mcp_config=cfg, enable_tools=enable_tools)","preventionTips":["Always pass tool filters as list[str]","Normalize external config values before constructing MCPClient","Add type hints (list[str] | None) at call sites to catch mistakes statically"],"tags":["mcp","type-validation","tool-filtering"],"backgroundTag":"type-mismatch-validation","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}