{"record":{"id":"b3e02e01bb829e87","repo":"n8n-io/n8n","slug":"delegated-child-input-is-missing-or-invalid","errorCode":null,"errorMessage":"Delegated child input is missing or invalid","messagePattern":"Delegated child input is missing or invalid","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts","lineNumber":499,"sourceCode":"\t) => await handleDelegateSubAgent(input, ctx, resolvedOptions, childPathIndexes);\n\tconst toModelOutput = (output: z.infer<typeof delegateSubAgentOutputSchema>) =>\n\t\tresolvedOptions.toModelOutput ? resolvedOptions.toModelOutput(output) : output;\n\tconst tool = resolvedOptions.resumeSubAgent\n\t\t? toolBuilder\n\t\t\t\t.suspend(delegateSubAgentSuspendSchema)\n\t\t\t\t.resume(delegateSubAgentResumeSchema)\n\t\t\t\t.handler(handler)\n\t\t\t\t.toModelOutput(toModelOutput)\n\t\t\t\t.build()\n\t\t: toolBuilder.handler(handler).toModelOutput(toModelOutput).build();\n\treturn withSdkOwnedBuiltInMetadata({\n\t\t...tool,\n\t\t...(resolvedOptions.cancelSubAgent !== undefined\n\t\t\t? {\n\t\t\t\t\tonCancellation: async (rawInput: unknown, ctx: ToolCancellationContext) => {\n\t\t\t\t\t\tconst parsedInput = delegateSubAgentInputSchema.safeParse(rawInput);\n\t\t\t\t\t\tif (!parsedInput.success) {\n\t\t\t\t\t\t\tthrow new Error('Delegated child input is missing or invalid');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait cancelDelegatedSubAgent(parsedInput.data, ctx, resolvedOptions, childPathIndexes);\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t\tmetadata: {\n\t\t\t...tool.metadata,\n\t\t\t[INLINE_DELEGATE_SUB_AGENT_TOOL_METADATA_KEY]: {\n\t\t\t\t...(resolvedOptions.name !== undefined ? { name: resolvedOptions.name } : {}),\n\t\t\t\t...(resolvedOptions.availableSubAgents !== undefined\n\t\t\t\t\t? { availableSubAgents: resolvedOptions.availableSubAgents }\n\t\t\t\t\t: {}),\n\t\t\t\tpolicy: resolvedOptions.policy,\n\t\t\t\t...(resolvedOptions.inlineSubAgentBlockedTools !== undefined\n\t\t\t\t\t? { inlineSubAgentBlockedTools: resolvedOptions.inlineSubAgentBlockedTools }\n\t\t\t\t\t: {}),\n\t\t\t\t...(resolvedOptions.inlineSubAgentModelsByDifficulty !== undefined\n\t\t\t\t\t? {","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts#L481-L517","documentation":"Thrown inside the onCancellation handler when delegateSubAgentInputSchema.safeParse(rawInput) fails. This means the raw input received by the cancellation path does not conform to the expected delegation input schema. Under normal operation the input should always be valid since it was produced by the tool's own input schema, so this error signals data corruption, a custom toModelOutput that mangled the payload, or a framework-level deserialization issue.","triggerScenarios":"The host runtime invokes onCancellation with a rawInput that is not a valid DelegateSubAgentInput (missing subAgentId, taskName, or malformed structure). Can happen if a custom serialization layer corrupts the tool call payload, or if the cancellation is triggered with stale data from a previous run.","commonSituations":"Checkpoint restoration after a server restart where the serialized tool input was migrated or schema-incompatible. Custom toModelOutput or input transform that strips required fields. Concurrent cancellation requests racing with schema changes.","solutions":["Ensure no custom middleware modifies the raw tool call input between the original call and the cancellation path.","If using checkpoint persistence, verify the serialized input round-trips correctly through your storage layer.","Check that the delegateSubAgentInputSchema version matches between the time the call was made and when cancellation fires (version skew).","Log the rawInput value before the parse to diagnose what field is missing or invalid."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrap the cancellation invocation if you control the host runtime:\ntry {\n  await tool.onCancellation?.(rawInput, ctx);\n} catch (e) {\n  logger.error('Cancellation input invalid', { error: e });\n  // fall back to a generic cancellation without parsed input\n}","preventionTips":["Do not modify or transform raw tool call inputs between the original call and cancellation.","Ensure checkpoint serialization round-trips the full tool input without field loss.","Keep the library version consistent across suspend and cancel paths to avoid schema drift."],"tags":["cancellation","delegate-tool","serialization","schema-validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}