{"record":{"id":"4dd129e4180601a8","repo":"n8n-io/n8n","slug":"unsupported-syntax-dynamic-method-name-is-not-a","errorCode":null,"errorMessage":"Unsupported syntax: 'Dynamic method name' is not allowed in SDK code","messagePattern":"Unsupported syntax: 'Dynamic method name' 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":245,"sourceCode":"\t\t\tif (memberExpr.object.type === 'Super') {\n\t\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t\t'super keyword is not supported in SDK code',\n\t\t\t\t\tmemberExpr.object.loc ?? undefined,\n\t\t\t\t\tthis.sourceCode,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Get method name\n\t\t\tlet methodName: string;\n\t\t\tif (memberExpr.property.type === 'Identifier') {\n\t\t\t\tmethodName = memberExpr.property.name;\n\t\t\t} else if (\n\t\t\t\tmemberExpr.property.type === 'Literal' &&\n\t\t\t\ttypeof memberExpr.property.value === 'string'\n\t\t\t) {\n\t\t\t\tmethodName = memberExpr.property.value;\n\t\t\t} else {\n\t\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t\t'Dynamic method name',\n\t\t\t\t\tmemberExpr.property.loc ?? undefined,\n\t\t\t\t\tthis.sourceCode,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Handle safe global methods (e.g. JSON.stringify, JSON.parse)\n\t\t\t// Must check before evaluating the object, since the global itself is blocked\n\t\t\tif (memberExpr.object.type === 'Identifier') {\n\t\t\t\tconst safeMethod = getSafeJSONMethod(memberExpr.object.name, methodName);\n\t\t\t\tif (safeMethod) {\n\t\t\t\t\tconst args = node.arguments.map((arg) => this.evaluate(arg));\n\t\t\t\t\treturn safeMethod(...args);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthisArg = this.evaluate(memberExpr.object);\n","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts#L227-L263","documentation":"In a method call `obj.method()`, the interpreter requires the method name to be statically resolvable — either a dot-access `Identifier` (`obj.add()`) or a string `Literal` key (`obj[\"add\"]()`). Computed method names using a runtime expression (`obj[dynamicKey]()`) are rejected at interpreter.ts:245 because they could resolve to any property, defeating the method allowlist.","triggerScenarios":"Writing `obj[methodName]()` or `obj[getKey()]()` where the bracket contains a non-literal expression. At interpreter.ts:237-250, the property must be an `Identifier` or a string `Literal`; anything else (a `CallExpression`, `MemberExpression`, `BinaryExpression`, etc.) triggers the throw.","commonSituations":"Dynamic dispatch patterns; selecting a builder method based on runtime data; porting code that uses computed method names for flexibility.","solutions":["Use a static method name: `obj.add()` or `obj['add']()` (string literal is allowed)","If dispatch is truly needed, use `ifElse` or `switchCase` SDK functions to branch to static calls","Move the dynamic dispatch into a Code node"],"exampleFix":"// before\nwf[methodName]({ name: 'X' });\n\n// after\nwf.add({ name: 'X' });","handlingStrategy":"validation","validationCode":"// Detect computed method calls (obj[expr]() where expr is not a string literal)\nfunction hasComputedMethod(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 === 'CallExpression' &&\n      node.callee.type === 'MemberExpression' &&\n      node.callee.computed &&\n      node.callee.property.type !== 'Literal'\n    ) {\n      found = true;\n    }\n  });\n  return found;\n}","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('Dynamic method name')) {\n    // instruct user to use static method names\n  }\n  throw e;\n}","preventionTips":["Always use dot notation for method calls: `obj.add()` not `obj[key]()`","If you need dispatch, branch with `ifElse`/`switchCase` to static calls"],"tags":["sdk-interpreter","dynamic-access","computed-method","security"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}