n8n-io/n8n · error · Error
Nodes from fromJSON() do not support onError()
Error message
Nodes from fromJSON() do not support onError()
What it means
Imported (fromJSON) node handles do not support onError(), which on authored nodes configures per-node error behavior (e.g. routing to an error output). Imported nodes read their error settings verbatim from the JSON's onError field, so the fluent mutator is disabled. The throw prevents silently losing error-handling config that the JSON already specifies.
Source
Thrown at packages/@n8n/workflow-sdk/src/workflow-builder/workflow-import.ts:103
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);
}
nodes.set(mapKey, {View on GitHub (pinned to 5ac6606e81)
Solutions
- Set the onError field in the source JSON before importing.
- Re-author the node with the builder factory and use its .onError() API.
- Use node.update({ onError: ... }) which is supported on imported handles (it returns a new config without touching connections).
Example fix
// before
const n = wf.getNode('X'); // imported
n.onError(...); // throws
// after (option A: edit JSON)
json.nodes.find(x => x.name === 'X').onError = 'stopOnError';
workflow.fromJSON(json);
// after (option B: update config)
const updated = n.update({ onError: 'stopOnError' }); Defensive patterns
Strategy: validation
Validate before calling
function isImportedNode(n: any): boolean {
return n.__imported === true;
}
if (isImportedNode(n)) {
// use update() which is supported, instead of onError()
return n.update({ onError: 'stopOnError' });
} Type guard
function isImportedNode(n: { __imported?: boolean }): boolean {
return n.__imported === true;
} Try / catch
try {
n.onError('stopOnError');
} catch (e) {
if (e instanceof Error && e.message.includes('fromJSON()')) {
return n.update({ onError: 'stopOnError' });
}
throw e;
} Prevention
- Set onError in the source JSON before importing.
- Use node.update({ onError }) on imported handles — it is supported.
- Re-author nodes that need fluent error-handling config.
When it happens
Trigger: Calling node.onError(...) on a handle from fromJSON() to change its error routing after import.
Common situations: Post-import normalization that tries to standardize error handling; helper code that sets onError uniformly on all nodes.
Related errors
- Nodes from fromJSON() do not support to()
- Nodes from fromJSON() do not support input()
- Nodes from fromJSON() do not support output()
- Subnode error handling is managed by parent node SubnodeConf
- INVALID_CONNECTION
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/38e138f667e236a2.
Report an issue: GitHub.