{"record":{"id":"9e8316bb496b952e","repo":"n8n-io/n8n","slug":"node-kind-declarations-are-not-allowed-use","errorCode":null,"errorMessage":"'${node.kind}' declarations are not allowed. Use 'const' only.","messagePattern":"'(.+?)' declarations are not allowed\\. Use 'const' only\\.","errorType":"exception","errorClass":"SecurityError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts","lineNumber":96,"sourceCode":"\t\t\t\t\tresult = this.evaluate(stmt.expression);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'ExportDefaultDeclaration':\n\t\t\t\t\treturn this.evaluate(stmt.declaration as ESTree.Expression);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new UnsupportedNodeError(stmt.type, stmt.loc ?? undefined, this.sourceCode);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Process a variable declaration.\n\t */\n\tprivate visitVariableDeclaration(node: ESTree.VariableDeclaration): void {\n\t\t// Only allow const declarations\n\t\tif (node.kind !== 'const') {\n\t\t\tthrow new SecurityError(\n\t\t\t\tnode.kind,\n\t\t\t\tnode.loc ?? undefined,\n\t\t\t\tthis.sourceCode,\n\t\t\t\t`'${node.kind}' declarations are not allowed. Use 'const' only.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const declarator of node.declarations) {\n\t\t\tif (declarator.id.type !== 'Identifier') {\n\t\t\t\tthrow new UnsupportedNodeError(\n\t\t\t\t\t'Destructuring in variable declaration',\n\t\t\t\t\tdeclarator.loc ?? undefined,\n\t\t\t\t\tthis.sourceCode,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst name = declarator.id.name;\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts#L78-L114","documentation":"Thrown as SecurityError (extends InterpreterError) by visitVariableDeclaration when a variable declaration's kind is not 'const'. The SDK vocabulary only permits const bindings to keep evaluated code referentially transparent and free of reassignment. The offending kind (let/var) is interpolated into the message and a code frame is appended when location is available.","triggerScenarios":"Writing `let x = 1;` or `var y = 2;` at the top level of SDK code; auto-formatters or codegen emitting let by default; refactoring const to let during debugging and forgetting to revert.","commonSituations":"Developers defaulting to let out of habit; copy-pasting snippets that use let/var; linters that rewrite const to let for later reassignment.","solutions":["Change every top-level declaration to const.","If reassignment is needed, restructure to a single const with a ternary or an SDK helper that returns the final value.","Run a lint rule that flags non-const declarations in SDK files."],"exampleFix":"// before\nlet result = compute(x);\nresult = result + 1;\nexport default result;\n// after\nconst base = compute(x);\nexport default base + 1;","handlingStrategy":"validation","validationCode":"import { parseSDKCode } from '@n8n/workflow-sdk';\n\nfunction preflightConstOnly(code: string): void {\n  const ast = parseSDKCode(code);\n  for (const stmt of ast.body) {\n    if (stmt.type === 'VariableDeclaration' && stmt.kind !== 'const') {\n      throw new Error(`SDK code must use 'const' (found '${stmt.kind}') near line ${stmt.loc?.start.line}`);\n    }\n  }\n}","typeGuard":"import type { VariableDeclaration } from 'estree';\n\nfunction isConstDeclaration(node: VariableDeclaration): boolean {\n  return node.kind === 'const';\n}","tryCatchPattern":"try {\n  return interpret(code, sdkFunctions);\n} catch (e) {\n  if (e?.name === 'SecurityError' && /declarations are not allowed/i.test(e?.message ?? '')) {\n    return { error: 'Use const only in SDK code.', detail: e.message };\n  }\n  throw e;\n}","preventionTips":["Use const for all top-level bindings in SDK code.","Restructture reassignment into a single const with a ternary or SDK helper result.","Add a lint rule flagging let/var in SDK files."],"tags":["workflow-sdk","ast-interpreter","validation","sandbox","security"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}