n8n-io/n8n · error · Error
Invalid delegate sub-agent tool name "${name}": must start w
Error message
Invalid delegate sub-agent tool name "${name}": must start with a letter and contain only letters, digits, underscores, and hyphens (max 64 characters) What it means
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.
Source
Thrown at packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts:390
!Number.isFinite(resolvedPolicy.maxChildren) ||
!Number.isInteger(resolvedPolicy.maxChildren)
) {
throw new Error(`${toolName} policy.maxChildren must be a finite positive integer`);
}
if (resolvedPolicy.maxChildren < 1) {
throw new Error(`${toolName} policy.maxChildren must be at least 1`);
}
return resolvedPolicy;
}
const DELEGATE_SUB_AGENT_TOOL_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;
function resolveDelegateSubAgentToolName(name: string | undefined): string {
if (name === undefined) return DELEGATE_SUB_AGENT_TOOL_NAME;
if (!DELEGATE_SUB_AGENT_TOOL_NAME_PATTERN.test(name)) {
throw new Error(
`Invalid delegate sub-agent tool name "${name}": must start with a letter and contain only letters, digits, underscores, and hyphens (max 64 characters)`,
);
}
return name;
}
const DEFAULT_DELEGATE_SUB_AGENT_DESCRIPTION =
'Delegate a bounded, self-contained subtask to a focused child agent that runs in an isolated context and returns only a concise final result. ' +
'Use it for reasoning-heavy subtasks, context-flooding investigations, or independent workstreams inside a larger deliverable. ' +
'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.';
function resolveDelegateSubAgentDescription(options: CreateDelegateSubAgentToolOptions): string {
const { description } = options;
if (typeof description === 'string' && description.trim().length > 0) return description;
return DEFAULT_DELEGATE_SUB_AGENT_DESCRIPTION;
}
View on GitHub (pinned to 5ac6606e81)
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.
Example fix
// before
const tool = createDelegateSubAgentTool({ name: '1st-helper' });
// after
const tool = createDelegateSubAgentTool({ name: 'helper-1' }); Defensive patterns
Strategy: validation
Validate before calling
const DELEGATE_TOOL_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;
function isValidDelegateToolName(name: string | undefined): boolean {
return name === undefined || DELEGATE_TOOL_NAME_RE.test(name);
}
// before calling createDelegateSubAgentTool:
if (!isValidDelegateToolName(options.name)) {
options.name = sanitizeToolName(options.name) ?? undefined;
} Type guard
function isDelegateToolName(name: unknown): name is string {
return typeof name === 'string' && /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/.test(name);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ${toolName} requires resumeSubAgent and cancelSubAgent to be
- Model ID is required
- Deferred tool name "${tool.name}" is reserved
- Duplicate deferred tool name "${tool.name}"
- ${toolName} was registered without a runSubAgent callback, a
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/83053017f260e5d0.
Report an issue: GitHub.