n8n-io/n8n · error · Error

Nodes from fromJSON() do not support input()

Error message

Nodes from fromJSON() do not support input()

What it means

Imported (fromJSON) node handles do not implement the fluent input() selector. input() is a builder-only construct used to select a specific input index on an authored node for targeted wiring; imported nodes carry their full connection graph verbatim from JSON and cannot be re-pointed this way. The method is present only to give a precise, actionable error rather than a generic 'not a function'.

Source

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

				disabled: n8nNode.disabled,
				notes: n8nNode.notes,
				notesInFlow: n8nNode.notesInFlow,
				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)) {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Re-author the node with the builder node() factory if you need input selection.
  2. Use workflow.connect(importedNode, 0, target, targetInput) to wire inputs explicitly.
  3. Branch helper logic on whether the handle came from fromJSON() vs an authored factory.

Example fix

// before
const n = wf.getNode('X'); // imported
n.input(1).to(target); // throws

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

Strategy: type-guard

Validate before calling

function isImportedNode(n: any): boolean {
  return typeof n.input === 'function' && n.input.toString().includes('fromJSON()');
}
// Prefer tracking origin explicitly rather than introspecting function bodies.

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling node.input(1) on a handle obtained from a fromJSON()-imported workflow, then chaining .to(target) or passing it to workflow.add().

Common situations: Generic helper functions that iterate node handles and call input()/output() uniformly across authored and imported nodes; refactoring that switches a workflow from builder-authored to JSON-imported without updating the wiring calls.

Related errors


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