n8n-io/n8n · error · Error

Nodes from fromJSON() do not support output()

Error message

Nodes from fromJSON() do not support output()

What it means

Imported (fromJSON) node handles do not implement output(). output() returns an OutputSelector on authored nodes so a specific output index of a branching node (IF, Switch) can be wired; imported nodes already encode all output connections in JSON, so the selector is unavailable. The throw is intentional to stop callers from producing half-wired selectors that connect nothing.

Source

Thrown at packages/@n8n/workflow-sdk/src/workflow-builder/workflow-import.ts:100

				executeOnce: n8nNode.executeOnce,
				retryOnFail: n8nNode.retryOnFail,
				maxTries: n8nNode.maxTries,
				waitBetweenTries: n8nNode.waitBetweenTries,
				alwaysOutputData: n8nNode.alwaysOutputData,
				onError: n8nNode.onError,
				extendsCredential: n8nNode.extendsCredential,
			},
			update(config) {
				return { ...this, config: { ...this.config, ...config } };
			},
			to() {
				throw new Error('Nodes from fromJSON() do not support to()');
			},
			input() {
				throw new Error('Nodes from fromJSON() do not support input()');
			},
			output() {
				throw new Error('Nodes from fromJSON() do not support output()');
			},
			onError() {
				throw new Error('Nodes from fromJSON() do not support onError()');
			},
			getConnections() {
				return [];
			},
		};

		const connectionsMap = new Map<string, Map<number, ConnectionTarget[]>>();
		let mapKey = nodeName || `__unnamed_${unnamedCounter++}`;

		// Handle duplicate node names: generate unique key for duplicates
		// The first instance keeps the original name (connections reference it)
		if (nodes.has(mapKey)) {
			mapKey = generateUniqueName(nodeName, (n) => nodes.has(n));
		} else {
			nameToKey.set(nodeName, mapKey);

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Re-author the branching node with the builder factories if you need output selection.
  2. Use workflow.connect(source, outputIndex, target, 0) to wire a specific output index.
  3. Edit the JSON connections map directly before importing.

Example fix

// before
const n = wf.getNode('If'); // imported
n.output(0).to(a); // throws

// after
wf.connect(n, 0, a, 0);
Defensive patterns

Strategy: type-guard

Validate before calling

function isImportedNode(n: any): boolean {
  return n.__imported === true;
}
if (isImportedNode(n)) {
  throw new Error('Cannot call output() on imported node; use wf.connect()');
}

Type guard

function isImportedNode(n: { __imported?: boolean }): boolean {
  return n.__imported === true;
}

Try / catch

try {
  n.output(0).to(target);
} catch (e) {
  if (e instanceof Error && e.message.includes('fromJSON()')) {
    wf.connect(n, 0, target, 0);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling node.output(0) on a node handle obtained via fromJSON(), then chaining .to(target) or passing the selector to workflow.add().

Common situations: Porting builder code that branched on IF/Switch outputs to an imported workflow; generic graph-walking utilities that assume all nodes support output().

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/be189ccd7fe37174. Report an issue: GitHub.