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

  1. 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.
  2. 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.
  3. Omit the name option entirely to use the built-in default DELEGATE_SUB_AGENT_TOOL_NAME.
  4. 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

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


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/83053017f260e5d0. Report an issue: GitHub.