n8n-io/n8n · error · Error
Maximum branch depth (${WorkflowBuilderImpl.MAX_BRANCH_DEPTH
Error message
Maximum branch depth (${WorkflowBuilderImpl.MAX_BRANCH_DEPTH}) exceeded while building workflow graph What it means
A recursion guard inside addBranchToGraph. Each nested branch increments a depth counter; if it reaches MAX_BRANCH_DEPTH (500) the builder throws rather than overflow the stack. The guard exists to detect cycles in branch chains (e.g. a NodeChain that references itself) which would otherwise recurse infinitely while flattening the graph. Under normal use with finite, acyclic chains the counter never approaches 500.
Source
Thrown at packages/@n8n/workflow-sdk/src/workflow-builder.ts:1093
this._currentNode = chain.tail?.name ?? headNodeName;
this._currentOutput = 0;
return this;
}
/**
* Add a branch to the graph, handling both single nodes and NodeChains.
* Returns the name of the first node in the branch (for connection from IF).
* @param nameMapping - Optional map from node ID to actual map key (used when nodes are renamed)
*/
private addBranchToGraph(
nodes: Map<string, GraphNode>,
branch: NodeInstance<string, string, unknown>,
nameMapping?: Map<string, string>,
): string {
// Guard against infinite recursion from cycles in branch chains
if (this._branchDepth >= WorkflowBuilderImpl.MAX_BRANCH_DEPTH) {
throw new Error(
`Maximum branch depth (${WorkflowBuilderImpl.MAX_BRANCH_DEPTH}) exceeded while building workflow graph`,
);
}
this._branchDepth++;
try {
return this._addBranchToGraphInner(nodes, branch, nameMapping);
} finally {
this._branchDepth--;
}
}
private _addBranchToGraphInner(
nodes: Map<string, GraphNode>,
branch: NodeInstance<string, string, unknown>,
nameMapping?: Map<string, string>,
): string {
// Create nameMapping if not passed (tracks node ID -> actual map key for renamed nodes)
const effectiveNameMapping = nameMapping ?? new Map<string, string>();View on GitHub (pinned to 5ac6606e81)
Solutions
- Inspect the branch being added for self-reference or mutual reference between composites; break the cycle.
- Audit the code that constructs NodeChains/branches for a missing base case in its loop or recursion.
- If the depth is legitimately large, refactor into a flatter structure.
Example fix
// before (buggy loop builds a self-referential chain)
let chain = node({ type: 'Set' });
chain = chain.to(chain); // cycle
workflow.add(trigger({})).to(chain); // throws at depth 500
// after
workflow.add(trigger({})).to(node({ type: 'Set' })); Defensive patterns
Strategy: validation
Validate before calling
const MAX = 500;
function chainDepth(chain: any, seen = new WeakSet()): number {
// walk the chain counting nesting, guard against cycles with `seen`
return depth;
}
if (chainDepth(branch) >= MAX) {
throw new Error('Branch chain too deep or cyclic');
} Type guard
function isCyclicReference(branch: any, seen = new WeakSet()): boolean {
if (typeof branch !== 'object' || branch === null) return false;
if (seen.has(branch)) return true;
seen.add(branch);
return Object.values(branch).some(v => isCyclicReference(v, seen));
} Try / catch
try {
wf.add(trigger({})).to(branch);
} catch (e) {
if (e instanceof Error && /Maximum branch depth/.test(e.message)) {
// inspect branch for self-reference and break the cycle
}
throw e;
} Prevention
- Never construct a NodeChain that references itself or its ancestor.
- Audit loop/recursion that builds chains for a missing base case.
- Flatten deeply nested legitimate chains below 500 levels.
When it happens
Trigger: A NodeChain or composite node whose branch references itself directly or indirectly, creating a cycle; programmatically generated node chains with a loop bug; a plugin that recursively dispatches to itself.
Common situations: Code that builds NodeChains in a loop with a faulty termination condition; composites that accidentally include themselves as members; very deep (but legitimate) nested chains that genuinely exceed 500 levels (rare).
Related errors
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f40046ee7df3db98.
Report an issue: GitHub.