n8n-io/n8n · error · InterpreterError
Expression nesting too deep (possible cycle in method chain)
Error message
Expression nesting too deep (possible cycle in method chain)
What it means
The interpreter evaluates expressions recursively and tracks depth in `this.evalDepth`. When depth reaches `MAX_EVAL_DEPTH` (500), it throws `InterpreterError` to prevent stack overflow. This guards against pathological nesting that could hang or crash the Node.js process — the message hints at method chains because chained calls (`a.b().c().d()`) recurse through `evaluate` at each step.
Source
Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts:146
this.sourceCode,
`'${name}' is a reserved SDK function name and cannot be used as a variable name. ` +
`Use a different name like 'my${name.charAt(0).toUpperCase() + name.slice(1)}'.`,
);
}
const value = declarator.init ? this.evaluate(declarator.init) : undefined;
this.variables.set(name, value);
}
}
/**
* Evaluate an expression and return its value.
*/
private evaluate(node: ESTree.Expression | ESTree.SpreadElement | null): unknown {
if (node === null) return undefined;
if (this.evalDepth >= SDKInterpreter.MAX_EVAL_DEPTH) {
throw new InterpreterError(
'Expression nesting too deep (possible cycle in method chain)',
node.loc ?? undefined,
this.sourceCode,
);
}
this.evalDepth++;
try {
return this.evaluateNode(node);
} finally {
this.evalDepth--;
}
}
private evaluateNode(node: ESTree.Expression | ESTree.SpreadElement): unknown {
validateNodeType(node, this.sourceCode);
switch (node.type) {View on GitHub (pinned to 5ac6606e81)
Solutions
- Break the expression into multiple `const` statements to flatten the evaluation tree
- If code is generated, cap chain length in the generator and emit intermediate consts
- Move bulk data into a separate JSON structure or Code node rather than inlining
Example fix
// before (one giant chain)
workflow({ name: 'X' }).add(n1).to(n2).add(n3).to(n4) /* ... 500+ calls ... */;
// after (flattened with consts)
const wf = workflow({ name: 'X' });
const step1 = wf.add(n1).to(n2);
const step2 = step1.add(n3).to(n4); Defensive patterns
Strategy: validation
Validate before calling
// Measure AST depth before interpreting
function maxExpressionDepth(ast: ESTree.Node): number {
let max = 0;
const visit = (node: any, depth: number) => {
max = Math.max(max, depth);
for (const child of Object.values(node)) {
if (Array.isArray(child)) child.forEach((c) => c?.type && visit(c, depth + 1));
else if (child?.type) visit(child, depth + 1);
}
};
visit(ast, 0);
return max;
}
const ast = parseSDKCode(sdkCode);
if (maxExpressionDepth(ast) > 450) {
// warn or reject before calling interpretSDKCode
} Try / catch
import { InterpreterError } from '@n8n/workflow-sdk/ast-interpreter/errors';
try {
interpretSDKCode(sdkCode, sdkFunctions);
} catch (e) {
if (e instanceof InterpreterError && e.message.includes('nesting too deep')) {
// suggest breaking the expression into multiple consts
}
throw e;
} Prevention
- Avoid chains longer than ~100 method calls in one expression
- Flatten generated code into intermediate `const` statements
- If generating SDK code, cap expression depth in the generator configuration
When it happens
Trigger: Writing an expression nested more than 500 levels deep — e.g., hundreds of chained `.to().add().to()` calls in one expression, or a massively nested object/array literal. Each recursive `evaluate` call increments `evalDepth`; at 500 the guard fires at interpreter.ts:145.
Common situations: Machine-generated SDK code that produces extremely long builder chains; inlining a huge data structure as a literal; deeply nested ternary or logical chains (`a && b && c && ...`).
Related errors
- Circular eager relations are disallowed. ${entityMetadata.ta
- Unsupported syntax: 'Destructuring in variable declaration'
- '${name}' is a reserved SDK function name and cannot be used
- Unknown identifier: '${identifier}' is not defined
- Unsupported syntax: 'super keyword is not supported in SDK c
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/85c31483e5dd339b.
Report an issue: GitHub.