n8n-io/n8n · error · UnsupportedNodeError
Unsupported syntax: 'Binary operator ${node.operator}' is no
Error message
Unsupported syntax: 'Binary operator ${node.operator}' is not allowed in SDK code What it means
Binary operators are restricted to arithmetic (`+`, `-`, `*`, `/`, `%`, `**`) and comparison (`==`, `!=`, `===`, `!==`, `<`, `<=`, `>`, `>=`). Bitwise operators (`|`, `&`, `^`, `<<`, `>>`, `>>>`) and relational operators (`in`, `instanceof`) throw `UnsupportedNodeError` at interpreter.ts:653 because they are rarely needed for workflow construction and bitwise ops are a common obfuscation vector.
Source
Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts:653
// eslint-disable-next-line eqeqeq
return left == right;
case '!=':
// eslint-disable-next-line eqeqeq
return left != right;
case '===':
return left === right;
case '!==':
return left !== right;
case '<':
return (left as number) < (right as number);
case '<=':
return (left as number) <= (right as number);
case '>':
return (left as number) > (right as number);
case '>=':
return (left as number) >= (right as number);
default:
throw new UnsupportedNodeError(
`Binary operator ${node.operator}`,
node.loc ?? undefined,
this.sourceCode,
);
}
}
/**
* Visit a logical expression.
*/
private visitLogicalExpression(node: ESTree.LogicalExpression): unknown {
const left = this.evaluate(node.left);
switch (node.operator) {
case '&&':
return left ? this.evaluate(node.right) : left;
case '||':
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Implementing JS || semanticsView on GitHub (pinned to 5ac6606e81)
Solutions
- For `in` checks: use property access and compare: `obj.prop !== undefined` or `obj.prop != null`
- For `instanceof`: use `typeof` (supported) or move to a Code node
- For bitwise ops: move to a Code node or n8n expression
Example fix
// before const hasName = 'name' in obj; // after const hasName = obj.name !== undefined;
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED_BINARY = new Set(['+','-','*','/','%','**','==','!=','===','!==','<','<=','>','>=']);
function findBadBinaryOperators(code: string): string[] {
const ast = parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
const bad: string[] = [];
walk(ast, (node) => {
if (node.type === 'BinaryExpression' && !ALLOWED_BINARY.has(node.operator)) {
bad.push(node.operator);
}
});
return bad;
} Try / catch
import { UnsupportedNodeError } from '@n8n/workflow-sdk/ast-interpreter/errors';
try {
interpretSDKCode(sdkCode, sdkFunctions);
} catch (e) {
if (e instanceof UnsupportedNodeError && e.message.includes('Binary operator')) {
// show allowed operators and suggest property-access alternatives for `in`
}
throw e;
} Prevention
- Allowed binary operators: arithmetic (`+`,`-`,`*`,`/`,`%`,`**`) and comparison (`==`,`!=`,`===`,`!==`,`<`,`<=`,`>`,`>=`)
- No bitwise operators (`|`,`&`,`^`,`<<`,`>>`) — move to Code node
- Replace `'key' in obj` with `obj.key !== undefined`
When it happens
Trigger: Writing `a | b`, `x in obj`, `y instanceof Z`, `n << 2`, or any bitwise/relational binary operator in SDK code. The switch at interpreter.ts:618 only has cases for the thirteen allowed operators.
Common situations: Bitwise flag manipulation; `in` operator for property existence checks; `instanceof` for type testing; porting algorithmic or low-level JS.
Related errors
- Unsupported syntax: 'Unary operator ${node.operator}' is not
- Unsupported syntax: 'Destructuring in variable declaration'
- '${name}' is a reserved SDK function name and cannot be used
- Expression nesting too deep (possible cycle in method chain)
- Unknown identifier: '${identifier}' is not defined
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/ee1d8b55814ce01a.
Report an issue: GitHub.