{"record":{"id":"5492b41019040446","repo":"n8n-io/n8n","slug":"toolname-policy-maxchildren-must-be-a-finite-po","errorCode":null,"errorMessage":"${toolName} policy.maxChildren must be a finite positive integer","messagePattern":"(.+?) policy\\.maxChildren must be a finite positive integer","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts","lineNumber":375,"sourceCode":"\ttoModelOutput?: (output: z.infer<typeof delegateSubAgentOutputSchema>) => unknown;\n}\n\nexport type DelegateSubAgentToolMetadata = CreateDelegateSubAgentToolOptions;\n\nfunction resolveDelegateSubAgentPolicy(\n\tpolicy: DelegateSubAgentPolicy | undefined,\n\ttoolName: string,\n): DelegateSubAgentPolicy {\n\tconst resolvedPolicy = {\n\t\t...policy,\n\t\tmaxChildren: policy?.maxChildren ?? DEFAULT_SUB_AGENT_MAX_CHILDREN,\n\t};\n\n\tif (\n\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}","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts#L357-L393","documentation":"`resolveDelegateSubAgentPolicy` validates the `maxChildren` field of the delegation policy, which controls how many child sub-agent runs may execute in parallel. It defaults to `DEFAULT_SUB_AGENT_MAX_CHILDREN` (10) when undefined, then checks `Number.isFinite` and `Number.isInteger`. This throws when `maxChildren` is `NaN`, `Infinity`, `-Infinity`, a float (e.g. 2.5), or a non-number type that survived into the resolved policy.","triggerScenarios":"Calling the delegate sub-agent tool factory with `policy: { maxChildren: NaN }`, `policy: { maxChildren: Infinity }`, `policy: { maxChildren: 2.5 }`, or `policy: { maxChildren: '5' as any }`. Also when `maxChildren` is parsed from user/config input that was not coerced to an integer.","commonSituations":"A UI or config field for 'max parallel sub-agents' accepted free-text and passed an uncoerced value. A JSON config had `maxChildren: 2.5` or `maxChildren: null` that was not caught upstream. Floating-point division produced a non-integer (e.g. `totalTasks / workers`).","solutions":["Check the `maxChildren` value being passed — log it before the factory call.","Coerce to an integer before passing: `Math.floor(Number(value))`, and validate it is finite.","If the value comes from user input, validate with a Zod schema (`z.number().int().finite().positive()`) before it reaches the policy resolver.","Omit `maxChildren` entirely if you want the default of 10."],"exampleFix":"// before:\ncreateDelegateSubAgentTool({ policy: { maxChildren: 2.5 } });\n\n// after:\ncreateDelegateSubAgentTool({ policy: { maxChildren: Math.floor(userInput) } });\n// or omit for default:\ncreateDelegateSubAgentTool({ }); // maxChildren defaults to 10","handlingStrategy":"validation","validationCode":"function validateMaxChildren(value: unknown): number {\n  const n = Number(value);\n  if (!Number.isFinite(n) || !Number.isInteger(n)) {\n    throw new Error('maxChildren must be a finite integer');\n  }\n  return n;\n}\n\nconst maxChildren = validateMaxChildren(policy?.maxChildren);\ncreateDelegateSubAgentTool({ policy: { maxChildren } });","typeGuard":"function isFinitePositiveInteger(value: unknown): value is number {\n  return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value);\n}","tryCatchPattern":null,"preventionTips":["Coerce maxChildren to an integer with Math.floor before passing.","Validate with a Zod schema (z.number().int().finite().positive()) at the config boundary.","Omit maxChildren entirely to use the default of 10."],"tags":["tools","delegate","sub-agent","validation","policy","numeric"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}