n8n-io/n8n · error
unimplemented
unimplemented
Error message
unimplemented
What it means
Returned as HTTP 501 {error:'unimplemented', reason:...} when startExecution.start() throws UnimplementedError. validateExecutableGraph() throws this for graph shapes the engine does not support yet: back-edges/loops (CAT-2875), multi-slot outputs (CAT-2874, error 300), and same-slot convergence (CAT-3982, error 301). The graph passed schema and structural checks but uses a not-yet-built execution path.
Source
Thrown at packages/@n8n/engine/src/server/routes/workflow-executions.ts:79
details: parsed.error.flatten(),
});
return;
}
try {
const result = await startExecution.start(parsed.data);
res.status(201).json(result);
} catch (error) {
if (error instanceof AdmittanceRejectedError) {
res.status(429).json({ error: 'admittance_rejected', reason: error.reason });
return;
}
if (error instanceof GraphValidationError) {
res.status(400).json({ error: 'invalid_graph', reason: error.message });
return;
}
if (error instanceof UnimplementedError) {
res.status(501).json({ error: 'unimplemented', reason: error.message });
return;
}
throw error;
}
});
return router;
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Read response.body.reason to identify which unimplemented path was hit (loops, multi-slot output, or convergence).
- For back-edges: unroll the loop or move the iterative logic into a single node.
- For multi-slot output: collapse to outputIndex 0 (see error 300).
- For convergence: route branches into distinct inputIndex values (see error 301).
- If the feature is required, track the corresponding CAT ticket and stay on the v1 engine until it lands.
Example fix
// before — loop via back-edge
edges: [{ from: 'process', to: 'check', inputIndex: 0 }, { from: 'check', to: 'process', inputIndex: 0, isBackEdge: true }]
// after — remove the back-edge; do iteration inside one node
edges: [{ from: 'process', to: 'check', inputIndex: 0 }] Defensive patterns
Strategy: validation
Validate before calling
function assertNoUnsupportedFeatures(graph) {
if (graph.edges.some(e => e.isBackEdge)) throw new Error('Loops not supported (CAT-2875)');
if (graph.edges.some(e => e.outputIndex !== undefined && e.outputIndex !== 0)) throw new Error('Multi-slot output not supported (CAT-2874)');
const seen = new Set();
for (const e of graph.edges) {
const slot = `${e.to}#${e.inputIndex ?? 0}`;
if (seen.has(slot)) throw new Error('Convergence not supported (CAT-3982)');
seen.add(slot);
}
} Type guard
function isFullySupportedGraph(graph) {
if (graph.edges.some(e => e.isBackEdge)) return false;
if (graph.edges.some(e => e.outputIndex !== undefined && e.outputIndex !== 0)) return false;
const seen = new Set();
for (const e of graph.edges) {
const slot = `${e.to}#${e.inputIndex ?? 0}`;
if (seen.has(slot)) return false;
seen.add(slot);
}
return true;
} Try / catch
const res = await fetch('/workflow-executions', { method: 'POST', body: JSON.stringify(payload) });
if (res.status === 501) {
const body = await res.json(); // body.error === 'unimplemented', body.reason names the feature
// restructure the graph to avoid the unsupported feature, or use the v1 engine
} Prevention
- Avoid back-edges (loops) until CAT-2875; unroll iteration into a single node.
- Use only output slot 0 until CAT-2874.
- Route converging branches into distinct inputIndex values until CAT-3982.
- Run assertNoUnsupportedFeatures(graph) before submitting.
When it happens
Trigger: POST /workflow-executions with a graph containing an edge where isBackEdge is true (a loop), an edge with outputIndex !== 0, or two edges into the same target input slot. Each maps to the same 501 envelope but a distinct reason string.
Common situations: Porting loop/iteration workflows before CAT-2875. Porting branching (IF/Switch) before CAT-2874. Porting Merge/fan-in before CAT-3982. The reason string tells you which feature gate was hit.
Related errors
- Edge ${edge.from} → ${edge.to} leaves output slot ${edge.out
- Node ${edge.to} has more than one edge into input slot ${edg
- invalid_graph
- unimplemented
- Edge ${edge.from} → ${edge.to} has slot index ${index}; slot
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/ff3b99baae6078e5.
Report an issue: GitHub.