{"record":{"id":"0d575aa9b8652c7b","repo":"n8n-io/n8n","slug":"tool-name-reservedtool-name-is-reserved-for-r","errorCode":null,"errorMessage":"Tool name \"${reservedTool.name}\" is reserved for runtime skills","messagePattern":"Tool name \"(.+?)\" is reserved for runtime skills","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/agent.ts","lineNumber":333,"sourceCode":"\t}\n\n\t/**\n\t * Add runtime-loadable skills to the agent. The model sees only a compact\n\t * name/description catalog in the system prompt, then calls `load_skill`\n\t * to retrieve the full instructions for a relevant skill.\n\t */\n\tskills(sourceOrSkills: RuntimeSkillSource | RuntimeSkill[]): this {\n\t\tconst source = Array.isArray(sourceOrSkills)\n\t\t\t? createRuntimeSkillSource(sourceOrSkills)\n\t\t\t: sourceOrSkills;\n\n\t\tthis.removeRuntimeSkillTools();\n\t\tthis.skillSource = source;\n\t\tif (source.registry.skills.length === 0) return this;\n\n\t\tconst reservedTool = this.tools.find((tool) => RUNTIME_SKILL_TOOL_NAMES.has(tool.name));\n\t\tif (reservedTool) {\n\t\t\tthrow new Error(`Tool name \"${reservedTool.name}\" is reserved for runtime skills`);\n\t\t}\n\n\t\tthis.tools.push(...createRuntimeSkillTools(source));\n\t\tthis.hasRuntimeSkillTool = true;\n\t\treturn this;\n\t}\n\n\t/** Add a provider-defined tool (e.g. Anthropic web search, OpenAI code interpreter). */\n\tproviderTool(builtProviderTool: BuiltProviderTool): this {\n\t\tthis.providerTools.push(builtProviderTool);\n\t\treturn this;\n\t}\n\n\t/** Read the declared tools. Lists only tools added via tool() */\n\tget declaredTools(): BuiltTool[] {\n\t\treturn this.tools;\n\t}\n","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/agent.ts#L315-L351","documentation":"Thrown by Agent.skills() when an existing tool in the agent's tool list has a name that is in the RUNTIME_SKILL_TOOL_NAMES reserved set. The library reserves specific tool names for its own runtime skill management tools (search_tools, load_tool), and registering a user tool with one of these names would shadow the runtime's ability to discover and load skills.","triggerScenarios":"Calling agent.skills(source) after having added a tool via .tools() whose name matches one of the reserved runtime skill tool names. Or calling .tools() with a reserved name and then activating skills.","commonSituations":"Naming a custom tool 'search_tools' or 'load_tool' (or whatever names are in RUNTIME_SKILL_TOOL_NAMES). Importing tools from another library that happens to use a reserved name. Copying tool names from documentation without checking against the reserved set.","solutions":["Rename the conflicting tool to a non-reserved name before calling .skills().","Check the RUNTIME_SKILL_TOOL_NAMES set (exported from the package) before naming custom tools.","Add skills before adding custom tools, so you know which names are taken."],"exampleFix":"// before\nagent.tools([myTool]).skills(skillSource); // myTool.name === 'search_tools'\n// after\nmyTool.name = 'my_search';\nagent.tools([myTool]).skills(skillSource);","handlingStrategy":"validation","validationCode":"import { RUNTIME_SKILL_TOOL_NAMES } from '@n8n/agents';\nfunction hasReservedToolName(tools: { name: string }[]): boolean {\n  return tools.some((t) => RUNTIME_SKILL_TOOL_NAMES.has(t.name));\n}\nif (hasReservedToolName(myTools)) {\n  // rename before calling .skills()\n}","typeGuard":"function isReservedSkillToolName(name: string, reserved: Set<string>): name is string {\n  return reserved.has(name);\n}","tryCatchPattern":null,"preventionTips":["Check tool names against RUNTIME_SKILL_TOOL_NAMES before adding skills.","Avoid naming custom tools 'search_tools' or 'load_tool'.","Add skills before custom tools so reserved names are known upfront."],"tags":["naming","reserved","skills","tools","configuration"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}