n8n-io/n8n · error · Error

${toolName} policy.maxChildren must be at least 1

Error message

${toolName} policy.maxChildren must be at least 1

What it means

After confirming `maxChildren` is a finite integer, `resolveDelegateSubAgentPolicy` checks that it is at least 1. Zero or negative values throw. `maxChildren` controls the maximum number of parallel child sub-agent runs; zero would mean no children can ever run, making the delegation tool useless, and negative values are nonsensical.

Source

Thrown at packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts:379

function resolveDelegateSubAgentPolicy(
	policy: DelegateSubAgentPolicy | undefined,
	toolName: string,
): DelegateSubAgentPolicy {
	const resolvedPolicy = {
		...policy,
		maxChildren: policy?.maxChildren ?? DEFAULT_SUB_AGENT_MAX_CHILDREN,
	};

	if (
		!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 =

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Clamp `maxChildren` to at least 1 before passing: `Math.max(1, value)`.
  2. If zero means 'disable delegation', do not create the delegate tool at all rather than passing `maxChildren: 0`.
  3. Add UI/config validation to reject values below 1.
  4. Omit `maxChildren` if the default of 10 is acceptable.

Example fix

// before:
createDelegateSubAgentTool({ policy: { maxChildren: 0 } });

// after:
createDelegateSubAgentTool({ policy: { maxChildren: Math.max(1, computedSlots) } });
// or if delegation should be disabled when slots are 0, don't create the tool:
if (availableSlots > 0) {
  agent.tool(createDelegateSubAgentTool({ policy: { maxChildren: availableSlots } }));
}
Defensive patterns

Strategy: validation

Validate before calling

function resolveMaxChildren(value: unknown): number {
  const n = typeof value === 'number' ? value : 10; // default
  return Math.max(1, Math.floor(n));
}

createDelegateSubAgentTool({ policy: { maxChildren: resolveMaxChildren(userValue) } });

Type guard

function isPositiveInteger(value: unknown): value is number {
  return typeof value === 'number' && Number.isInteger(value) && value >= 1;
}

Prevention

When it happens

Trigger: Calling the delegate sub-agent tool factory with `policy: { maxChildren: 0 }` or `policy: { maxChildren: -3 }`. This happens when a computation produces zero or negative (e.g. `availableSlots - reservedSlots` where reserved exceeds available).

Common situations: A dynamic computation of `maxChildren` produced zero (e.g. `totalCapacity - usedCapacity` where all capacity is used). A config field defaulted to 0. A UI let the user set 0 thinking it meant 'unlimited'.

Related errors


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