{"record":{"id":"c235abce380708c0","repo":"n8n-io/n8n","slug":"failed-to-parse-workflow-code-error-message-c","errorCode":null,"errorMessage":"Failed to parse workflow code: ${error.message}. Common causes include unclosed template literals, missing commas, or unbalanced brackets.","messagePattern":"Failed to parse workflow code: (.+?)\\. Common causes include unclosed template literals, missing commas, or unbalanced brackets\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/codegen/parse-workflow-code.ts","lineNumber":634,"sourceCode":"\t\tconst wf = interpretSDKCode(executableCode, sdkFunctions);\n\n\t\t// Return the JSON representation\n\t\treturn (wf as { toJSON: () => WorkflowJSON }).toJSON();\n\t} catch (error) {\n\t\tif (error instanceof SecurityError) {\n\t\t\t// Re-throw security errors with more context\n\t\t\tthrow new SyntaxError(\n\t\t\t\t`Failed to parse workflow code: ${error.message}. ` +\n\t\t\t\t\t'This code contains patterns that are not allowed for security reasons.',\n\t\t\t);\n\t\t}\n\t\tif (error instanceof InterpreterError) {\n\t\t\t// Check for reserved SDK name conflicts\n\t\t\tif (error.message.includes('reserved SDK function name')) {\n\t\t\t\tthrow new SyntaxError(`Failed to parse workflow code: ${error.message}`);\n\t\t\t}\n\t\t\t// Convert interpreter errors to syntax errors for consistent API\n\t\t\tthrow new SyntaxError(\n\t\t\t\t`Failed to parse workflow code: ${error.message}. ` +\n\t\t\t\t\t'Common causes include unclosed template literals, missing commas, or unbalanced brackets.',\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Parses generated TypeScript SDK code and returns the WorkflowBuilder.\n * This allows callers to validate the graph structure before converting to JSON.\n *\n * Uses a secure AST-based interpreter instead of eval/new Function().\n *\n * @param code - TypeScript code generated by generateWorkflowCode()\n * @returns The WorkflowBuilder instance (call validate() then toJSON() on it)\n *\n * @example","sourceCodeStart":616,"sourceCodeEnd":652,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/codegen/parse-workflow-code.ts#L616-L652","documentation":"Thrown by parseWorkflowCode when interpretSDKCode raises a generic InterpreterError that is NOT the reserved-name case. The error is re-thrown as a SyntaxError with a 'common causes' hint pointing at unclosed template literals, missing commas, or unbalanced brackets. This catches interpreter-time evaluation failures and unsupported-syntax errors.","triggerScenarios":"Any InterpreterError during interpretation: syntax errors from the parser (1143), unsupported node types (1144/1145), null-property assignment (1141), or any other InterpreterError subclass that is not a SecurityError and does not mention 'reserved SDK function name'.","commonSituations":"Genuinely malformed code (typos); using a forbidden construct whose error bubbled up as InterpreterError; assigning to a property of null; hitting an allowlisted-but-unhandled node.","solutions":["Read the underlying InterpreterError message embedded in the SyntaxError — it carries the specific cause (and often a code frame).","Fix the root cause per that sub-error (syntax fix, remove unsupported construct, etc.).","If the hint about template literals/commas/brackets applies, validate bracket balance in a JS editor.","For unsupported-syntax errors, see the matching error index (1140–1145) for the targeted fix."],"exampleFix":"// before — code passed to parseWorkflowCode has e.g.:\n// const cfg = null; cfg.x = 1;  // 1141-style\n\n// after\nconst cfg = { x: 1 };","handlingStrategy":"try-catch","validationCode":"import { parseSDKCode } from '@n8n/workflow-sdk/ast-interpreter/parser';\nimport { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';\n\nfunction dryRun(code: string, sdkFunctions: unknown): { ok: true } | { ok: false; message: string } {\n  try {\n    parseSDKCode(code);\n    interpretSDKCode(code, sdkFunctions as never);\n    return { ok: true };\n  } catch (e) {\n    return { ok: false, message: (e as Error).message.split('\\n')[0] };\n  }\n}","typeGuard":"function bracketsBalanced(code: string): boolean {\n  const stack: string[] = [];\n  const pairs: Record<string, string> = { ')': '(', ']': '[', '}': '{' };\n  let inStr: string | null = null;\n  for (const ch of code) {\n    if (inStr) { if (ch === inStr) inStr = null; continue; }\n    if (ch === '\\'' || ch === '\"' || ch === '`') { inStr = ch; continue; }\n    if ('([{'.includes(ch)) stack.push(ch);\n    else if (')]}'.includes(ch) && stack.pop() !== pairs[ch]) return false;\n  }\n  return stack.length === 0;\n}","tryCatchPattern":"import { parseWorkflowCode } from '@n8n/workflow-sdk/codegen/parse-workflow-code';\n\ntry {\n  parseWorkflowCode(code);\n} catch (e) {\n  if (e instanceof SyntaxError && /Common causes include/.test(e.message)) {\n    // generic interpreter error — read embedded detail and fix root cause\n  }\n  throw e;\n}","preventionTips":["Validate bracket/backtick balance before submitting code.","Run parseSDKCode in a try/catch as a dry-run to surface the underlying InterpreterError early.","Match the embedded InterpreterError text to its specific sub-error (1140–1145) for the targeted fix."],"tags":["sdk","codegen","parse-workflow-code","interpreter-error","syntax-error-wrapper"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}