n8n-io/n8n · error · Error
SplitInBatches node output connections are managed by SplitI
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().
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)
Solutions
- Configure output targets through the builder's each/done branches.
- Use the fluent builder's .onEachBatch() / .onDone() (fluent variant) to bind output targets.
- 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
- Never call .output() on a SplitInBatches node; configure each/done branches via the builder.
- Filter SplitInBatches nodes out of generic fan-out loops.
- Use the builder's getConnection() / getAllNodes() to inspect declared edges.
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
- SplitInBatches node input connections are managed by SplitIn
- SplitInBatches node connections are managed by SplitInBatche
- SplitInBatches node error handling is managed by SplitInBatc
- Named object syntax does not support .onEachBatch() - branch
- Named object syntax does not support .onDone() - branches ar
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f23552bc8b0087d9.
Report an issue: GitHub.