{"record":{"id":"d4afaa4e80f7b959","repo":"n8n-io/n8n","slug":"deferred-tool-name-collision-the-following-tool","errorCode":null,"errorMessage":"Deferred tool name collision — the following tool names resolve to duplicates or reserved tools: ${deferredCollisions.join(', ')}","messagePattern":"Deferred tool name collision — the following tool names resolve to duplicates or reserved tools: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/agent.ts","lineNumber":1025,"sourceCode":"\t\tconst reservedDeferredToolNames = new Set([\n\t\t\tSEARCH_TOOLS_TOOL_NAME,\n\t\t\tLOAD_TOOL_TOOL_NAME,\n\t\t\t...RUNTIME_SKILL_TOOL_NAMES,\n\t\t]);\n\t\tconst deferredNames = new Set<string>();\n\t\tconst deferredCollisions: string[] = [];\n\t\tfor (const tool of finalDeferredTools) {\n\t\t\tif (\n\t\t\t\tstaticNames.has(tool.name) ||\n\t\t\t\treservedDeferredToolNames.has(tool.name) ||\n\t\t\t\tdeferredNames.has(tool.name)\n\t\t\t) {\n\t\t\t\tdeferredCollisions.push(tool.name);\n\t\t\t}\n\t\t\tdeferredNames.add(tool.name);\n\t\t}\n\t\tif (deferredCollisions.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Deferred tool name collision — the following tool names resolve to duplicates or reserved tools: ${deferredCollisions.join(', ')}`,\n\t\t\t);\n\t\t}\n\n\t\tconst collisions = mcpTools\n\t\t\t.filter((t) => staticNames.has(t.name) || deferredNames.has(t.name))\n\t\t\t.map((t) => t.name);\n\t\tif (collisions.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`MCP tool name collision — the following tool names resolve to duplicates: ${collisions.join(', ')}`,\n\t\t\t);\n\t\t}\n\n\t\tlet allTools = [...finalStaticTools, ...mcpTools];\n\n\t\t// Validate checkpoint again after discovering actual MCP tools\n\t\t// (catches the case where MCP tools have suspendSchema after listing).\n\t\tconst allNeedCheckpoint =","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/agent.ts#L1007-L1043","documentation":"Thrown by Agent.build() when a deferred tool name collides with an existing static tool name, another deferred tool name, or a reserved tool name (SEARCH_TOOLS_TOOL_NAME, LOAD_TOOL_TOOL_NAME, or any RUNTIME_SKILL_TOOL_NAMES). Deferred tools are loaded on demand, so name conflicts are checked against the full namespace to prevent ambiguity at call time.","triggerScenarios":"Registering a deferred tool whose name matches a static tool, another deferred tool, or a reserved runtime name. Deferred tools are added via the deferred tool registration path and checked against staticNames, reservedDeferredToolNames, and deferredNames sets.","commonSituations":"A deferred tool factory generating a name that overlaps with a static tool added in the same build. Using a reserved name like 'search_tools' for a deferred tool. Combining deferred tools from multiple modules with overlapping names.","solutions":["Rename the colliding deferred tool to a unique name not present in static, reserved, or other deferred tools.","Check the error message which lists the colliding names and resolve each one.","Avoid using reserved names (check RUNTIME_SKILL_TOOL_NAMES, SEARCH_TOOLS_TOOL_NAME, LOAD_TOOL_TOOL_NAME)."],"exampleFix":"// before\nagent.tools([{ name: 'fetch', ... }])\n     .deferredTools([{ name: 'fetch', factory: ... }]); // collision\n// after\nagent.tools([{ name: 'fetch', ... }])\n     .deferredTools([{ name: 'lazy_fetch', factory: ... }]);","handlingStrategy":"validation","validationCode":"const RESERVED = new Set([SEARCH_TOOLS_TOOL_NAME, LOAD_TOOL_TOOL_NAME, ...RUNTIME_SKILL_TOOL_NAMES]);\nfunction findDeferredCollisions(staticTools: { name: string }[], deferredTools: { name: string }[]): string[] {\n  const staticNames = new Set(staticTools.map((t) => t.name));\n  const seen = new Set<string>();\n  const collisions: string[] = [];\n  for (const t of deferredTools) {\n    if (staticNames.has(t.name) || RESERVED.has(t.name) || seen.has(t.name)) collisions.push(t.name);\n    seen.add(t.name);\n  }\n  return collisions;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check deferred tool names against static tool names, reserved names, and other deferred names before building.","Avoid using reserved names (search_tools, load_tool, runtime skill names) for deferred tools.","Namespace deferred tools to avoid overlaps with static tools."],"tags":["tools","naming","collision","deferred","reserved","agent"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}