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
- Clamp `maxChildren` to at least 1 before passing: `Math.max(1, value)`.
- If zero means 'disable delegation', do not create the delegate tool at all rather than passing `maxChildren: 0`.
- Add UI/config validation to reject values below 1.
- 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
- Clamp maxChildren to at least 1: Math.max(1, value).
- If zero means 'disable', conditionally skip creating the delegate tool.
- Validate with z.number().int().min(1) at the config boundary.
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
- ${toolName} policy.maxChildren must be a finite positive int
- Deferred tool name "${tool.name}" is reserved
- Duplicate deferred tool name "${tool.name}"
- Unable to convert tool to N8nTool: ${JSON.stringify(tool)}
- jitterRatio must be at least 0 and below 1, got ${lifecycleO
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/34dd7243fb9d5d94.
Report an issue: GitHub.