{"record":{"id":"741da51fa43b20bd","repo":"n8n-io/n8n","slug":"unsupported-syntax-only-property-assignment-e-g","errorCode":null,"errorMessage":"Unsupported syntax: 'Only property assignment (e.g., obj.prop = value) is allowed. Variable reassignment is not permitted.' is not allowed in SDK code","messagePattern":"Unsupported syntax: 'Only property assignment \\(e\\.g\\., obj\\.prop = value\\) is allowed\\. Variable reassignment is not permitted\\.' is not allowed in SDK code","errorType":"exception","errorClass":"UnsupportedNodeError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts","lineNumber":706,"sourceCode":"\t\tconst test = this.evaluate(node.test);\n\t\treturn test ? this.evaluate(node.consequent) : this.evaluate(node.alternate);\n\t}\n\n\t/**\n\t * Visit an assignment expression.\n\t * Only allows simple property assignment (obj.prop = value).\n\t */\n\tprivate visitAssignmentExpression(node: ESTree.AssignmentExpression): unknown {\n\t\tif (node.operator !== '=') {\n\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t`Assignment operator '${node.operator}' is not allowed. Only '=' is permitted.`,\n\t\t\t\tnode.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t);\n\t\t}\n\n\t\tif (node.left.type !== 'MemberExpression') {\n\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t'Only property assignment (e.g., obj.prop = value) is allowed. Variable reassignment is not permitted.',\n\t\t\t\tnode.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t);\n\t\t}\n\n\t\tvalidateMemberExpression(node.left, this.sourceCode);\n\n\t\tif (node.left.object.type === 'Super') {\n\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t'super keyword is not supported in SDK code',\n\t\t\t\tnode.left.object.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t);\n\t\t}\n\n\t\tconst obj = this.evaluate(node.left.object);\n","sourceCodeStart":688,"sourceCodeEnd":724,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts#L688-L724","documentation":"The interpreter only allows property assignment (`obj.prop = value`) where the left side is a `MemberExpression`. Direct variable reassignment (`x = newValue`) is rejected at interpreter.ts:705 because SDK code is designed to be declarative — `const`-only bindings, no mutation of variable bindings themselves. Object property mutation is permitted, but rebinding a name to a new value is not.","triggerScenarios":"Writing `x = 5` where `x` is a variable identifier (not a property access). The check `node.left.type !== 'MemberExpression'` at interpreter.ts:705 fires before any other validation, catching any assignment whose left side is an `Identifier` or other non-member node.","commonSituations":"Imperative-style code that reuses variable names for different values; accumulator patterns (`total = total + 1`); porting `let`-based loops.","solutions":["Use a new `const` with a different name for the updated value: `const totalUpdated = total + 1`","If mutating an object property, use `obj.prop = newValue` (property assignment IS allowed)","Move stateful or accumulator logic to a Code node"],"exampleFix":"// before\nlet total = 0;\ntotal = total + 5;\n\n// after\nconst total = 5;\n// or, accumulating on an object (allowed):\nconst state = {};\nstate.total = state.total + 5;","handlingStrategy":"validation","validationCode":"// Detect variable reassignment (assignment to non-MemberExpression)\nfunction hasVariableReassignment(code: string): boolean {\n  const ast = parse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n  let found = false;\n  walk(ast, (node) => {\n    if (\n      node.type === 'AssignmentExpression' &&\n      node.operator === '=' &&\n      node.left.type !== 'MemberExpression'\n    ) {\n      found = true;\n    }\n  });\n  return found;\n}\n\nif (hasVariableReassignment(sdkCode)) {\n  // reject — suggest using a new const or property assignment","typeGuard":null,"tryCatchPattern":"import { UnsupportedNodeError } from '@n8n/workflow-sdk/ast-interpreter/errors';\n\ntry {\n  interpretSDKCode(sdkCode, sdkFunctions);\n} catch (e) {\n  if (e instanceof UnsupportedNodeError && e.message.includes('Variable reassignment')) {\n    // suggest using a new const or obj.prop = value pattern\n  }\n  throw e;\n}","preventionTips":["SDK code is `const`-only — never reassign a variable binding","Use new const names for updated values: `const total2 = total1 + 1`","Property mutation IS allowed: `obj.prop = value`","Move stateful/imperative logic to a Code node"],"tags":["sdk-interpreter","assignment","immutability","const-only"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}