{"record":{"id":"b70e225198e62d37","repo":"n8n-io/n8n","slug":"named-object-syntax-does-not-support-oneachbatch","errorCode":null,"errorMessage":"Named object syntax does not support .onEachBatch() - branches are configured in the constructor","messagePattern":"Named object syntax does not support \\.onEachBatch\\(\\) - branches are configured in the constructor","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts","lineNumber":541,"sourceCode":"\n\t\tif (branches.each !== null) {\n\t\t\tconst firstEachNodes = getFirstNodes(branches.each);\n\t\t\tif (firstEachNodes.length > 1) {\n\t\t\t\tthis._eachBatches.push(firstEachNodes);\n\t\t\t} else if (firstEachNodes.length === 1) {\n\t\t\t\tthis._eachBatches.push(firstEachNodes[0]);\n\t\t\t}\n\t\t\t// For named syntax, we DON'T set _hasLoop because the loop is already\n\t\t\t// expressed in the connection target (e.g., each: sibNode or each: processNode.to(sibNode))\n\t\t\t// The workflow-builder's _hasLoop handling is only for the fluent API's .loop() method\n\t\t}\n\t}\n\n\t/**\n\t * Fluent API: Not supported for named syntax builder (use constructor branches instead)\n\t */\n\tonEachBatch(_target: BranchTarget): this {\n\t\tthrow new Error(\n\t\t\t'Named object syntax does not support .onEachBatch() - branches are configured in the constructor',\n\t\t);\n\t}\n\n\t/**\n\t * Fluent API: Not supported for named syntax builder (use constructor branches instead)\n\t */\n\tonDone(_target: BranchTarget): this {\n\t\tthrow new Error(\n\t\t\t'Named object syntax does not support .onDone() - branches are configured in the constructor',\n\t\t);\n\t}\n\n\tgetAllNodes(): Array<NodeInstance<string, string, unknown>> {\n\t\treturn [this.sibNode, ...this._doneNodes, ...this._eachNodes];\n\t}\n\n\tgetDoneNodes(): Array<NodeInstance<string, string, unknown>> {","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts#L523-L559","documentation":"Thrown by NamedSplitInBatchesBuilderImpl.onEachBatch(). The named-object form of splitInBatches() fixes the each and done branches at construction time (via the branches object), so the fluent .onEachBatch() method — which appends to the each branch after construction — is not supported on this builder variant.","triggerScenarios":"Constructing a SplitInBatches builder with the named-object syntax `splitInBatches('sib', { each, done })` and then calling .onEachBatch(target) on the returned builder.","commonSituations":"Developer starts with named syntax then tries to append fluent calls; refactoring between named and fluent styles halfway through; copy-paste from a fluent-style example onto a named-syntax builder.","solutions":["Provide the each branch in the constructor object: splitInBatches('sib', { each: handler, done: endNode }).","If you need .onEachBatch(), switch to the fluent builder variant that supports it.","Do not mix named-object construction with fluent branch methods."],"exampleFix":"// before\nconst sib = splitInBatches('sib', { done: endNode });\nsib.onEachBatch(processNode); // throws\n// after\nconst sib = splitInBatches('sib', { each: processNode, done: endNode });","handlingStrategy":"type-guard","validationCode":"function isNamedSyntaxBuilder(b: unknown): boolean {\n  return b instanceof NamedSplitInBatchesBuilderImpl;\n}\n\nif (isNamedSyntaxBuilder(builder)) {\n  throw new Error('Use constructor branches { each, done }, not .onEachBatch()');\n}","typeGuard":"function supportsFluentBranches(b: SplitInBatchesBuilder): boolean {\n  // named-syntax builders throw on .onEachBatch(); fluent builders do not\n  return !Object.is(b.onEachBatch, NamedSplitInBatchesBuilderImpl.prototype.onEachBatch);\n}","tryCatchPattern":"try {\n  builder.onEachBatch(target);\n} catch (e) {\n  if (e instanceof Error && /Named object syntax does not support/.test(e.message)) {\n    // reconfigure via constructor branches instead\n  }\n  throw e;\n}","preventionTips":["Decide named vs fluent style per SplitInBatches and stay consistent.","When using named syntax, supply `each` in the constructor object.","Reserve .onEachBatch() for the fluent builder variant."],"tags":["runtime","builder","split-in-batches","fluent-api"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}