{"record":{"id":"d2e943960754e052","repo":"agentscope-ai/agentscope","slug":"invalid-skill-or-loader-must-be-a-skill-ski","errorCode":null,"errorMessage":"Invalid skill or loader: {_}. Must be a skill, skill loader, or directory path.","messagePattern":"Invalid skill or loader: (.+?)\\. Must be a skill, skill loader, or directory path\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/agentscope/tool/_tool_group.py","lineNumber":94,"sourceCode":"            )\n\n        self.name = name\n        self.description = description or \"\"\n        self.instructions = instructions\n        self.tools = tools or []\n        self.mcps = mcps or []\n\n        # Skill\n        self.skills_or_loaders = []\n        for _ in skills_or_loaders or []:\n            if isinstance(_, str):\n                self.skills_or_loaders.append(LocalSkillLoader(directory=_))\n\n            elif isinstance(_, (Skill, SkillLoaderBase)):\n                self.skills_or_loaders.append(_)\n\n            else:\n                raise TypeError(\n                    f\"Invalid skill or loader: {_}. Must be a skill, \"\n                    f\"skill loader, or directory path.\",\n                )\n\n    async def list_skills(self) -> list[Skill]:\n        \"\"\"List all the skills in this tool group.\"\"\"\n        skills = []\n        for skill_or_loader in self.skills_or_loaders:\n            if isinstance(skill_or_loader, Skill):\n                skills.append(skill_or_loader)\n            elif isinstance(skill_or_loader, SkillLoaderBase):\n                skills.extend(await skill_or_loader.list_skills())\n\n        return skills\n","sourceCodeStart":76,"sourceCodeEnd":109,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/tool/_tool_group.py#L76-L109","documentation":"ToolGroup.__init__ validates each item in skills/mcps: it must be a Skill instance, a SkillLoaderBase, or a string directory path; anything else raises TypeError naming the offending object.","triggerScenarios":"Passing a module, a class instead of an instance, a Path object, or an arbitrary object in the skills list.","commonSituations":"Passing pathlib.Path instead of str; passing Skill (class) rather than Skill(...); passing a loader from an incompatible version with a different base class.","solutions":["Convert Path to str: str(path)","Instantiate skills: Skill(...) rather than the class","Ensure custom loaders subclass SkillLoaderBase from the installed agentscope version"],"exampleFix":"# before\nToolGroup(name='x', description='d', skills=[Path('./skills')])\n# after\nToolGroup(name='x', description='d', skills=['./skills'])","handlingStrategy":"validation","validationCode":"from pathlib import Path\nitems = [str(i) if isinstance(i, Path) else i for i in skills]","typeGuard":"from agentscope.tool import Skill, SkillLoaderBase\ndef valid_skill_item(o) -> bool:\n    return isinstance(o, str) or isinstance(o, (Skill, SkillLoaderBase))","tryCatchPattern":null,"preventionTips":["Convert Path to str before passing","Pass instances, not classes","Subclass SkillLoaderBase for custom loaders"],"tags":["tool-group","typeerror","validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}