{"record":{"id":"83053017f260e5d0","repo":"n8n-io/n8n","slug":"invalid-delegate-sub-agent-tool-name-name-mu","errorCode":null,"errorMessage":"Invalid delegate sub-agent tool name \"${name}\": must start with a letter and contain only letters, digits, underscores, and hyphens (max 64 characters)","messagePattern":"Invalid delegate sub-agent tool name \"(.+?)\": must start with a letter and contain only letters, digits, underscores, and hyphens \\(max 64 characters\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts","lineNumber":390,"sourceCode":"\t\t!Number.isFinite(resolvedPolicy.maxChildren) ||\n\t\t!Number.isInteger(resolvedPolicy.maxChildren)\n\t) {\n\t\tthrow new Error(`${toolName} policy.maxChildren must be a finite positive integer`);\n\t}\n\n\tif (resolvedPolicy.maxChildren < 1) {\n\t\tthrow new Error(`${toolName} policy.maxChildren must be at least 1`);\n\t}\n\n\treturn resolvedPolicy;\n}\n\nconst DELEGATE_SUB_AGENT_TOOL_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;\n\nfunction resolveDelegateSubAgentToolName(name: string | undefined): string {\n\tif (name === undefined) return DELEGATE_SUB_AGENT_TOOL_NAME;\n\tif (!DELEGATE_SUB_AGENT_TOOL_NAME_PATTERN.test(name)) {\n\t\tthrow new Error(\n\t\t\t`Invalid delegate sub-agent tool name \"${name}\": must start with a letter and contain only letters, digits, underscores, and hyphens (max 64 characters)`,\n\t\t);\n\t}\n\treturn name;\n}\n\nconst DEFAULT_DELEGATE_SUB_AGENT_DESCRIPTION =\n\t'Delegate a bounded, self-contained subtask to a focused child agent that runs in an isolated context and returns only a concise final result. ' +\n\t'Use it for reasoning-heavy subtasks, context-flooding investigations, or independent workstreams inside a larger deliverable. ' +\n\t'Do not use it for trivial work, single tool calls, mechanical steps, tasks that need hidden conversation context, or pass-through delegation of the entire user request.';\n\nfunction resolveDelegateSubAgentDescription(options: CreateDelegateSubAgentToolOptions): string {\n\tconst { description } = options;\n\tif (typeof description === 'string' && description.trim().length > 0) return description;\n\n\treturn DEFAULT_DELEGATE_SUB_AGENT_DESCRIPTION;\n}\n","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts#L372-L408","documentation":"Thrown by resolveDelegateSubAgentToolName when the optional name passed to createDelegateSubAgentTool fails the regex /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/. The library enforces this because the name becomes both the tool name exposed to the LLM and part of the agent's tool namespace, so it must be model-safe and collision-free. Names starting with a digit, containing spaces or special characters, empty strings, or exceeding 64 characters are rejected.","triggerScenarios":"Calling createDelegateSubAgentTool({ name: '...' }) where the string starts with a digit, contains characters outside [a-zA-Z0-9_-], is an empty string, or is longer than 64 characters. Also triggered by names with leading/trailing hyphens or underscores if the overall pattern fails, and by names containing dots, slashes, or colons.","commonSituations":"Auto-generating tool names from user-provided labels or task titles (e.g. 'my agent 1', 'agent.sub', '/helper'). Copying tool names from a config that used a different naming convention (snake_case with leading underscore, or namespaced with a colon). Migrating from a system that allowed numeric prefixes.","solutions":["Sanitize the name before passing it: trim whitespace, strip non-[a-zA-Z0-9_-] characters, ensure the first character is a letter, truncate to 64 characters.","If the name comes from user input, validate it client-side with the same regex /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/ before calling createDelegateSubAgentTool.","Omit the name option entirely to use the built-in default DELEGATE_SUB_AGENT_TOOL_NAME.","Write a helper that prefixes a letter if the first character is a digit, e.g. 'a_' + name."],"exampleFix":"// before\nconst tool = createDelegateSubAgentTool({ name: '1st-helper' });\n// after\nconst tool = createDelegateSubAgentTool({ name: 'helper-1' });","handlingStrategy":"validation","validationCode":"const DELEGATE_TOOL_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;\nfunction isValidDelegateToolName(name: string | undefined): boolean {\n  return name === undefined || DELEGATE_TOOL_NAME_RE.test(name);\n}\n// before calling createDelegateSubAgentTool:\nif (!isValidDelegateToolName(options.name)) {\n  options.name = sanitizeToolName(options.name) ?? undefined;\n}","typeGuard":"function isDelegateToolName(name: unknown): name is string {\n  return typeof name === 'string' && /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/.test(name);\n}","tryCatchPattern":null,"preventionTips":["Validate tool names against the regex /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/ before passing them to createDelegateSubAgentTool.","When generating names from user input, sanitize first: strip invalid chars, prefix a letter if the first char is a digit.","Omit the name option to use the safe default DELEGATE_SUB_AGENT_TOOL_NAME when you do not need a custom name."],"tags":["validation","delegate-tool","naming","configuration"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}