{"record":{"id":"2a3b722f4606a6a9","repo":"n8n-io/n8n","slug":"code-must-export-a-workflow-built-with-the-workflo","errorCode":null,"errorMessage":"Code must export a workflow built with the workflow() SDK function.","messagePattern":"Code must export a workflow built with the workflow\\(\\) SDK function\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/codegen/parse-workflow-code.ts","lineNumber":707,"sourceCode":"}\n\n/**\n * Coerce an interpreter result into a WorkflowBuilder.\n *\n * - If the result is already a WorkflowBuilder (produced by the SDK `workflow()` function), return it directly.\n * - If the result is a plain object that looks like WorkflowJSON (has a `nodes` array), convert it via `workflow.fromJSON()`.\n * - Otherwise, throw with a descriptive error.\n */\nfunction asWorkflowBuilder(result: unknown): WorkflowBuilder {\n\tif (isWorkflowBuilder(result)) {\n\t\treturn result;\n\t}\n\n\tif (isWorkflowJSON(result)) {\n\t\treturn workflowFn.fromJSON(result);\n\t}\n\n\tthrow new SyntaxError('Code must export a workflow built with the workflow() SDK function.');\n}\n","sourceCodeStart":689,"sourceCodeEnd":709,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/codegen/parse-workflow-code.ts#L689-L709","documentation":"Thrown by asWorkflowBuilder (called by parseWorkflowCodeToBuilder) when the interpreter's top-level result is neither a WorkflowBuilder (produced by calling workflow()) nor a WorkflowJSON-shaped plain object (something with a `nodes` array). The SDK contract requires that code exports a workflow built via the workflow() SDK function.","triggerScenarios":"SDK code whose `export default` evaluates to: a primitive (string/number/boolean), an array that is not a nodes-array shaped object, a plain object without a `nodes` property, undefined/null, or code that calls an SDK function other than workflow() at the top level without wrapping in workflow().","commonSituations":"Forgetting to wrap nodes in `workflow().add(...)`; exporting only a single node() result; exporting a configuration object; code that returns a builder that is not the WorkflowBuilder type (e.g., a node builder).","solutions":["Ensure the code's `export default` is a call to `workflow()` chained with `.add(...)`: `export default workflow().add(node('X'))`.","If building from JSON, use `workflow.fromJSON(jsonObj)` and export that.","Check that the export is not accidentally a node() builder or a plain config object — only a WorkflowBuilder or WorkflowJSON passes the shape guards.","Verify isWorkflowBuilder/isWorkflowJSON expectations: a WorkflowJSON must have a top-level `nodes` array."],"exampleFix":"// before\nexport default node('Http').parameters({ url: 'https://x' });\n\n// after\nexport default workflow()\n  .add(node('Http').parameters({ url: 'https://x' }));","handlingStrategy":"type-guard","validationCode":"import { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';\n\nfunction isWorkflowJSON(v: unknown): v is { nodes: unknown[] } {\n  return typeof v === 'object' && v !== null && Array.isArray((v as { nodes?: unknown[] }).nodes);\n}\n\n// After interpretation, verify shape BEFORE calling asWorkflowBuilder\nconst result = interpretSDKCode(code, sdkFunctions);\nif (!isWorkflowBuilder(result) && !isWorkflowJSON(result)) {\n  throw new Error('Code must export a workflow built with the workflow() SDK function.');\n}","typeGuard":"// Guard for the WorkflowJSON shape (has a nodes array)\nfunction isWorkflowJSON(v: unknown): v is { nodes: unknown[]; connections?: unknown } {\n  return typeof v === 'object' && v !== null && Array.isArray((v as { nodes?: unknown[] }).nodes);\n}\n\n// Guard for the WorkflowBuilder shape (duck-typed on .toJSON and .validate)\nfunction isWorkflowBuilder(v: unknown): v is { toJSON: () => unknown; validate: () => unknown } {\n  return typeof v === 'object' && v !== null\n    && typeof (v as { toJSON?: unknown }).toJSON === 'function'\n    && typeof (v as { validate?: unknown }).validate === 'function';\n}","tryCatchPattern":"import { parseWorkflowCodeToBuilder } from '@n8n/workflow-sdk/codegen/parse-workflow-code';\n\ntry {\n  const builder = parseWorkflowCodeToBuilder(code);\n} catch (e) {\n  if (e instanceof SyntaxError && /must export a workflow built with the workflow\\(\\) SDK function/.test(e.message)) {\n    // instruct: wrap the export in workflow().add(...) or use workflow.fromJSON()\n  }\n  throw e;\n}","preventionTips":["Always structure SDK code as `export default workflow().add(...)`.","If importing from JSON, use `workflow.fromJSON(json)` and export that result.","Do not export a bare node() result or a config object — only a WorkflowBuilder or WorkflowJSON passes the shape guards."],"tags":["sdk","codegen","as-workflow-builder","missing-workflow-export","shape-mismatch"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}