{"record":{"id":"26d9e673e31406b4","repo":"n8n-io/n8n","slug":"nodes-from-fromjson-do-not-support-to","errorCode":null,"errorMessage":"Nodes from fromJSON() do not support to()","messagePattern":"Nodes from fromJSON\\(\\) do not support to\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/workflow-builder/workflow-import.ts","lineNumber":94,"sourceCode":"\t\t\t\t...({ _originalName: n8nNode.name } as Record<string, unknown>),\n\t\t\t\tposition: n8nNode.position,\n\t\t\t\twebhookId: n8nNode.webhookId,\n\t\t\t\tdisabled: n8nNode.disabled,\n\t\t\t\tnotes: n8nNode.notes,\n\t\t\t\tnotesInFlow: n8nNode.notesInFlow,\n\t\t\t\texecuteOnce: n8nNode.executeOnce,\n\t\t\t\tretryOnFail: n8nNode.retryOnFail,\n\t\t\t\tmaxTries: n8nNode.maxTries,\n\t\t\t\twaitBetweenTries: n8nNode.waitBetweenTries,\n\t\t\t\talwaysOutputData: n8nNode.alwaysOutputData,\n\t\t\t\tonError: n8nNode.onError,\n\t\t\t\textendsCredential: n8nNode.extendsCredential,\n\t\t\t},\n\t\t\tupdate(config) {\n\t\t\t\treturn { ...this, config: { ...this.config, ...config } };\n\t\t\t},\n\t\t\tto() {\n\t\t\t\tthrow new Error('Nodes from fromJSON() do not support to()');\n\t\t\t},\n\t\t\tinput() {\n\t\t\t\tthrow new Error('Nodes from fromJSON() do not support input()');\n\t\t\t},\n\t\t\toutput() {\n\t\t\t\tthrow new Error('Nodes from fromJSON() do not support output()');\n\t\t\t},\n\t\t\tonError() {\n\t\t\t\tthrow new Error('Nodes from fromJSON() do not support onError()');\n\t\t\t},\n\t\t\tgetConnections() {\n\t\t\t\treturn [];\n\t\t\t},\n\t\t};\n\n\t\tconst connectionsMap = new Map<string, Map<number, ConnectionTarget[]>>();\n\t\tlet mapKey = nodeName || `__unnamed_${unnamedCounter++}`;\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/workflow-builder/workflow-import.ts#L76-L112","documentation":"Nodes produced by fromJSON() are read-only snapshots: their connections are already fully described in the imported JSON, so the fluent connection-builder methods are intentionally disabled. The .to() method throws because re-wiring an imported node would conflict with the connections already encoded in the JSON. Only nodes authored via the builder factories (trigger/node/etc.) support the fluent .to()/.input()/.output()/.onError() API.","triggerScenarios":"Calling fromJSON(workflowJson) to import a workflow, then taking a node handle from the result and invoking node.to(target) to add a new outgoing connection. Also triggered by helpers that internally call .to() on an imported node handle.","commonSituations":"A user imports an existing n8n workflow JSON and tries to extend it imperatively; migration scripts that mix fromJSON import with builder-style chaining; code that treats all node handles uniformly without distinguishing authored vs imported nodes.","solutions":["If you need to extend an imported workflow, re-author the relevant nodes with the builder factories (trigger/node) instead of mutating imported handles.","Use the workflow builder's .connect(source, sourceOutput, target, targetInput) method to add connections at the workflow level rather than via node.to().","Edit the source JSON before calling fromJSON() to inject the desired connections."],"exampleFix":"// before\nconst wf = workflow.fromJSON(json);\nwf.getNode('MyNode').to(otherNode); // throws\n\n// after\nconst wf = workflow.fromJSON(json);\nwf.connect(importedNode, 0, otherNode, 0);","handlingStrategy":"type-guard","validationCode":"function supportsFluentAPI(node: unknown): boolean {\n  // Imported nodes' to() throws; authored nodes' to() returns a chain.\n  // Track origin separately rather than probing at runtime.\n  return (node as any)?.__imported !== true;\n}","typeGuard":"import type { NodeInstance } from 'workflow-sdk';\n\nfunction isAuthoredNode(n: NodeInstance & { __imported?: boolean }): boolean {\n  return n.__imported !== true;\n}","tryCatchPattern":"try {\n  importedNode.to(target);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('fromJSON()')) {\n    wf.connect(importedNode, 0, target, 0);\n  } else throw e;\n}","preventionTips":["Do not mix fromJSON-imported handles with the fluent .to() API; use workflow.connect() for imported nodes.","Re-author nodes with builder factories when you need the fluent connection API.","Tag imported handles (e.g. __imported = true) so generic helpers can branch."],"tags":["workflow-builder","fromjson","import","connections"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}