{"record":{"id":"8fa470cca688bc77","repo":"n8n-io/n8n","slug":"methodname-must-immediately-follow-adding-a","errorCode":null,"errorMessage":".${methodName}() must immediately follow adding a ${expected} node. Use it as ${usage}.","messagePattern":"\\.(.+?)\\(\\) must immediately follow adding a (.+?) node\\. Use it as (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/workflow-builder.ts","lineNumber":429,"sourceCode":"\tprivate branchFromCurrent(\n\t\toutputIndex: number,\n\t\ttarget: unknown,\n\t\tmethodName: 'onTrue' | 'onFalse' | 'onCase',\n\t): WorkflowBuilder {\n\t\tconst sourceKey = this._currentNode;\n\t\tconst sourceType = sourceKey ? this._nodes.get(sourceKey)?.instance.type : undefined;\n\t\tconst wantsSwitch = methodName === 'onCase';\n\t\tconst matches = sourceType\n\t\t\t? wantsSwitch\n\t\t\t\t? isSwitchNodeType(sourceType)\n\t\t\t\t: isIfNodeType(sourceType)\n\t\t\t: false;\n\t\tif (!matches) {\n\t\t\tconst expected = wantsSwitch ? 'Switch' : 'IF';\n\t\t\tconst usage = wantsSwitch\n\t\t\t\t? 'workflow.add(trigger).to(switchNode).onCase(0, a).onCase(1, b)'\n\t\t\t\t: 'workflow.add(trigger).to(ifNode).onTrue(a).onFalse(b)';\n\t\t\tthrow new Error(\n\t\t\t\t`.${methodName}() must immediately follow adding a ${expected} node. Use it as ${usage}.`,\n\t\t\t);\n\t\t}\n\n\t\tif (target === null || target === undefined) {\n\t\t\tthis._currentNode = sourceKey;\n\t\t\tthis._currentOutput = 0;\n\t\t\treturn this;\n\t\t}\n\n\t\tthis._currentNode = sourceKey;\n\t\tthis._currentOutput = outputIndex;\n\t\tthis.to(target as NodeInstance<string, string, unknown>);\n\t\t// Re-anchor the cursor on the branching node so the next sibling branch wires correctly.\n\t\tthis._currentNode = sourceKey;\n\t\tthis._currentOutput = 0;\n\t\treturn this;\n\t}","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/workflow-builder.ts#L411-L447","documentation":"The branching helpers onTrue()/onFalse()/onCase() must be called when the builder cursor is positioned on an IF (for onTrue/onFalse) or Switch (for onCase) node. The guard inspects the type of the node the cursor currently points to and rejects the call if it is not the expected branching type. The error message tells you exactly which node type is required and shows the correct chaining pattern.","triggerScenarios":"Calling workflow.add(trigger({...})).to(regularNode).onTrue(a) — onTrue() runs but the cursor is on regularNode, not an IF node. Or calling onCase() after an IF node instead of a Switch node. Also triggered when the cursor has been advanced off the branching node by an intervening .to() that did not re-anchor.","commonSituations":"Forgetting to add the IF/Switch node before branching; chaining extra .to() calls between adding the IF and calling onTrue/onFalse so the cursor drifts; using onCase with an IF or onTrue with a Switch.","solutions":["Add the IF node and immediately call .onTrue(...)/.onFalse(...) on the same chain (the builder re-anchors the cursor on the branching node for sibling branches).","For Switch nodes, use .onCase(index, target) and ensure the source is a Switch node.","Verify the node type passed to isIfNodeType/isSwitchNodeType matches the method you are calling."],"exampleFix":"// before\nworkflow.add(trigger({})).to(node({ type: 'Set' })).onTrue(a); // throws\n\n// after\nworkflow.add(trigger({})).to(ifNode({ type: 'If' })).onTrue(a).onFalse(b);","handlingStrategy":"validation","validationCode":"import { isIfNodeType, isSwitchNodeType } from 'workflow-sdk';\n\nconst sourceType = wf.getCursorNodeType?.();\nif (methodName === 'onCase' && !isSwitchNodeType(sourceType)) {\n  throw new Error('Add a Switch node before calling onCase()');\n}\nif ((methodName === 'onTrue' || methodName === 'onFalse') && !isIfNodeType(sourceType)) {\n  throw new Error('Add an IF node before calling onTrue()/onFalse()');\n}","typeGuard":"function isBranchingFor(method: 'onTrue'|'onFalse'|'onCase', nodeType: string): boolean {\n  return method === 'onCase' ? isSwitchNodeType(nodeType) : isIfNodeType(nodeType);\n}","tryCatchPattern":"try {\n  wf.add(trigger({})).to(ifNode({ type: 'If' })).onTrue(a);\n} catch (e) {\n  if (e instanceof Error && /must immediately follow/.test(e.message)) {\n    // cursor not on a branching node; restructure the chain\n  }\n  throw e;\n}","preventionTips":["Call onTrue/onFalse immediately after adding the IF node; call onCase immediately after adding the Switch node.","Avoid chaining non-branching .to() calls between the branching node and the branch helpers.","Match onCase with Switch and onTrue/onFalse with IF."],"tags":["workflow-builder","branching","if-node","switch-node"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}