n8n-io/n8n · error · Error

SplitInBatches node output connections are managed by…

Error message

SplitInBatches node output connections are managed by SplitInBatchesBuilder

What it means

Thrown by SplitInBatchesNodeInstance.output(). The SplitInBatches node's output ports (each / done) are owned by SplitInBatchesBuilder, which is the only place that can correctly declare which output index a downstream node binds to. Calling .output() on the raw node is blocked for the same ownership reason as .input().

Solutions

  1. Configure output targets through the builder's each/done branches.
  2. Use the fluent builder's .onEachBatch() / .onDone() (fluent variant) to bind output targets.
  3. Do not call .output() on a SplitInBatches node.

Example fix

// before
sibNode.output(0).to(processNode);
// after
splitInBatches('sib', { each: processNode, done: endNode });
Defensive patterns

Strategy: type-guard

Validate before calling

function safeOutput(node: NodeInstance, i: number): OutputSelector<any, any, any> {
  if (node.type === 'n8n-nodes-base.splitInBatches') {
    throw new Error('Use SplitInBatchesBuilder each/done branches instead of .output()');
  }
  return node.output(i);
}

Type guard

function isSplitInBatches(node: NodeInstance): node is NodeInstance<'n8n-nodes-base.splitInBatches', string, unknown> {
  return node.type === 'n8n-nodes-base.splitInBatches';
}

Prevention

When it happens

Trigger: Calling sibNode.output(0) or sibNode.output(1) directly to get an OutputSelector; generic code that fans out via .output(i) for every multi-output node.

Common situations: Treating SplitInBatches like a generic multi-output node; constructing a manual connection from a specific SIB output index.

Related errors


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

Appendix: source

Thrown at packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts:60

	update(
		config: Partial<NodeConfig>,
	): NodeInstance<'n8n-nodes-base.splitInBatches', string, unknown> {
		return new SplitInBatchesNodeInstance({
			version: this.version,
			config: {
				...this.config,
				...config,
			},
		});
	}

	input(_index: number): InputTarget {
		throw new Error('SplitInBatches node input connections are managed by SplitInBatchesBuilder');
	}

	output(_index: number): OutputSelector<'n8n-nodes-base.splitInBatches', string, unknown> {
		throw new Error('SplitInBatches node output connections are managed by SplitInBatchesBuilder');
	}

	to<T extends NodeInstance<string, string, unknown>>(
		_target: T | T[] | InputTarget,
		_outputIndex?: number,
	): NodeChain<NodeInstance<'n8n-nodes-base.splitInBatches', string, unknown>, T> {
		throw new Error('SplitInBatches node connections are managed by SplitInBatchesBuilder');
	}

	onError<T extends NodeInstance<string, string, unknown>>(_handler: T): this {
		throw new Error('SplitInBatches node error handling is managed by SplitInBatchesBuilder');
	}

	getConnections(): DeclaredConnection[] {
		return [];
	}
}

View on GitHub (pinned to 5ac6606e81)