n8n-io/n8n · error · Error

Delegated child input is missing or invalid

Error message

Delegated child input is missing or invalid

What it means

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.

Source

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

	) => await handleDelegateSubAgent(input, ctx, resolvedOptions, childPathIndexes);
	const toModelOutput = (output: z.infer<typeof delegateSubAgentOutputSchema>) =>
		resolvedOptions.toModelOutput ? resolvedOptions.toModelOutput(output) : output;
	const tool = resolvedOptions.resumeSubAgent
		? toolBuilder
				.suspend(delegateSubAgentSuspendSchema)
				.resume(delegateSubAgentResumeSchema)
				.handler(handler)
				.toModelOutput(toModelOutput)
				.build()
		: toolBuilder.handler(handler).toModelOutput(toModelOutput).build();
	return withSdkOwnedBuiltInMetadata({
		...tool,
		...(resolvedOptions.cancelSubAgent !== undefined
			? {
					onCancellation: async (rawInput: unknown, ctx: ToolCancellationContext) => {
						const parsedInput = delegateSubAgentInputSchema.safeParse(rawInput);
						if (!parsedInput.success) {
							throw new Error('Delegated child input is missing or invalid');
						}
						await cancelDelegatedSubAgent(parsedInput.data, ctx, resolvedOptions, childPathIndexes);
					},
				}
			: {}),
		metadata: {
			...tool.metadata,
			[INLINE_DELEGATE_SUB_AGENT_TOOL_METADATA_KEY]: {
				...(resolvedOptions.name !== undefined ? { name: resolvedOptions.name } : {}),
				...(resolvedOptions.availableSubAgents !== undefined
					? { availableSubAgents: resolvedOptions.availableSubAgents }
					: {}),
				policy: resolvedOptions.policy,
				...(resolvedOptions.inlineSubAgentBlockedTools !== undefined
					? { inlineSubAgentBlockedTools: resolvedOptions.inlineSubAgentBlockedTools }
					: {}),
				...(resolvedOptions.inlineSubAgentModelsByDifficulty !== undefined
					? {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Ensure no custom middleware modifies the raw tool call input between the original call and the cancellation path.
  2. If using checkpoint persistence, verify the serialized input round-trips correctly through your storage layer.
  3. Check that the delegateSubAgentInputSchema version matches between the time the call was made and when cancellation fires (version skew).
  4. Log the rawInput value before the parse to diagnose what field is missing or invalid.
Defensive patterns

Strategy: try-catch

Try / catch

// Wrap the cancellation invocation if you control the host runtime:
try {
  await tool.onCancellation?.(rawInput, ctx);
} catch (e) {
  logger.error('Cancellation input invalid', { error: e });
  // fall back to a generic cancellation without parsed input
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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