n8n-io/n8n · error

Sub-agent tool requires confirmation but no HITL handler is

Error message

Sub-agent tool requires confirmation but no HITL handler is available

What it means

Thrown by consumeStreamWithHitl (consume-with-hitl.ts:81-83) when options.waitForConfirmation is not provided. Because the function's contract is to suspend on tool-call-suspended chunks and resume after confirmation, a missing handler means suspension cannot be satisfied — the guard fails fast before any streaming begins rather than deadlocking mid-stream.

Source

Thrown at packages/@n8n/instance-ai/src/stream/consume-with-hitl.ts:82

			: result.status === 'errored'
				? 'failed while streaming'
				: `ended with unexpected status "${result.status}"`;
	throw new Error(`${agentLabel} ${reason}`);
}

/**
 * Consume a sub-agent stream with HITL suspend/resume support.
 * Detects `tool-call-suspended` chunks, waits for user confirmation,
 * and resumes the stream. Used by delegate, builder, and other agent tools.
 *
 * Returns `{ text }` — a promise for the agent's full text output.
 * When HITL occurred, this returns the resumed stream's text (not the original).
 */
export async function consumeStreamWithHitl(
	options: ConsumeWithHitlOptions,
): Promise<ConsumeWithHitlResult> {
	if (!options.waitForConfirmation) {
		throw new Error('Sub-agent tool requires confirmation but no HITL handler is available');
	}

	const stream = normalizeStreamSource(options.stream);
	const result = await executeResumableStream({
		agent: options.agent,
		stream,
		context: {
			threadId: options.threadId,
			runId: options.runId,
			agentId: options.agentId,
			eventBus: options.eventBus,
			signal: options.abortSignal,
			logger: options.logger,
			outputRedaction: options.outputRedaction,
		},
		control: {
			mode: 'auto',
			waitForConfirmation: options.waitForConfirmation,

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Pass a waitForConfirmation callback in ConsumeWithHitlOptions when calling consumeStreamWithHitl.
  2. If the call site never needs HITL, use the non-HITL consume path instead.
  3. In tests, provide a mock waitForConfirmation even if it is not exercised.
  4. Audit the tool wiring to confirm the handler is threaded from the orchestrator context.

Example fix

// before: consumeStreamWithHitl({ agent, stream, runId, agentId, eventBus, logger, threadId, abortSignal })
// after:  consumeStreamWithHitl({ agent, stream, runId, agentId, eventBus, logger, threadId, abortSignal, waitForConfirmation })
Defensive patterns

Strategy: type-guard

Validate before calling

function hasHitlHandler(opts: { waitForConfirmation?: unknown }): boolean {
  return typeof opts.waitForConfirmation === 'function';
}
if (!hasHitlHandler(options)) throw new Error('consumeStreamWithHitl requires waitForConfirmation');

Type guard

function hasWaitForConfirmation(o: unknown): o is { waitForConfirmation: (id: string) => Promise<Record<string, unknown>> } {
  return typeof (o as { waitForConfirmation?: unknown })?.waitForConfirmation === 'function';
}

Try / catch

try { return await consumeStreamWithHitl(options); }
catch (e) {
  if (e instanceof Error && e.message === 'Sub-agent tool requires confirmation but no HITL handler is available') {
    // this is a programming error; fix the call site, do not retry as-is
  }
  throw e;
}

Prevention

When it happens

Trigger: consumeStreamWithHitl is invoked without a waitForConfirmation callback. This is a programming error in the caller (the tool wiring), not a runtime data condition. The check runs synchronously on entry.

Common situations: A new sub-agent tool forgot to thread the HITL handler through; a test stub omitted waitForConfirmation; a non-HITL call site mistakenly used consumeStreamWithHitl instead of a plain consume helper.

Related errors


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