{"record":{"id":"63fd6af65f23f77b","repo":"n8n-io/n8n","slug":"cannot-call-output-on-the-workflow-builder-use","errorCode":null,"errorMessage":"Cannot call .output() on the workflow builder. Use .output() on a node variable instead: myNode.output(0).to(targetNode)","messagePattern":"Cannot call \\.output\\(\\) on the workflow builder\\. Use \\.output\\(\\) on a node variable instead: myNode\\.output\\(0\\)\\.to\\(targetNode\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/workflow-builder.ts","lineNumber":450,"sourceCode":"\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}\n\n\toutput(): never {\n\t\tthrow new Error(\n\t\t\t'Cannot call .output() on the workflow builder. ' +\n\t\t\t\t'Use .output() on a node variable instead: myNode.output(0).to(targetNode)',\n\t\t);\n\t}\n\n\tinput(): never {\n\t\tthrow new Error(\n\t\t\t'Cannot call .input() on the workflow builder. ' +\n\t\t\t\t'Use .input() on a node variable instead: myNode.input(1)',\n\t\t);\n\t}\n\n\tsettings(settings: WorkflowSettings): WorkflowBuilder {\n\t\tthis._settings = { ...this._settings, ...settings };\n\t\treturn this;\n\t}\n\n\tconnect(","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/workflow-builder.ts#L432-L468","documentation":"The WorkflowBuilder object itself does not have a meaningful .output() — output selection is per-node. The method exists on the builder only to intercept the common mistake of writing workflow.output(0).to(...) instead of myNode.output(0).to(...). Calling it always throws. Use .output() on a node handle returned by trigger()/node()/add().","triggerScenarios":"Typing workflow.output(0).to(target) instead of first capturing a node handle and calling node.output(0).to(target). Often a copy-paste from node-handle code onto the workflow object.","commonSituations":"Confusing the workflow-level API with the node-level API; refactoring that loses the node variable reference; IDE autocomplete picking workflow.output because the node handle is out of scope.","solutions":["Capture the node handle: const myNode = node({ type: 'If' }); then myNode.output(0).to(target).","Pass the OutputSelector to workflow.add(): workflow.add(myNode.output(0).to(target))."],"exampleFix":"// before\nworkflow.output(0).to(target); // throws\n\n// after\nconst myNode = node({ type: 'Some' });\nworkflow.add(myNode.output(0).to(target));","handlingStrategy":"type-guard","validationCode":"if (typeof (wf as any).output === 'function') {\n  // .output() on the builder always throws; call it on a node handle instead.\n}\nconst myNode = node({ type: 'Some' });\nconst selector = myNode.output(0); // correct","typeGuard":"function isWorkflowBuilder(v: unknown): v is WorkflowBuilder {\n  return typeof v === 'object' && v !== null && 'add' in v && 'to' in v && 'settings' in v;\n}","tryCatchPattern":null,"preventionTips":["Never call .output() on the workflow object; capture a node handle first.","Keep node handle variables in scope so autocomplete prefers the node's .output().","Review fluent chains to confirm .output() is chained on a node, not the workflow."],"tags":["workflow-builder","api-misuse","output-selector"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}