n8n-io/n8n · error · SyntaxError

Code must export a workflow built with the workflow() SDK fu

Error message

Code must export a workflow built with the workflow() SDK function.

What it means

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.

Source

Thrown at packages/@n8n/workflow-sdk/src/codegen/parse-workflow-code.ts:707

}

/**
 * Coerce an interpreter result into a WorkflowBuilder.
 *
 * - If the result is already a WorkflowBuilder (produced by the SDK `workflow()` function), return it directly.
 * - If the result is a plain object that looks like WorkflowJSON (has a `nodes` array), convert it via `workflow.fromJSON()`.
 * - Otherwise, throw with a descriptive error.
 */
function asWorkflowBuilder(result: unknown): WorkflowBuilder {
	if (isWorkflowBuilder(result)) {
		return result;
	}

	if (isWorkflowJSON(result)) {
		return workflowFn.fromJSON(result);
	}

	throw new SyntaxError('Code must export a workflow built with the workflow() SDK function.');
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Ensure the code's `export default` is a call to `workflow()` chained with `.add(...)`: `export default workflow().add(node('X'))`.
  2. If building from JSON, use `workflow.fromJSON(jsonObj)` and export that.
  3. Check that the export is not accidentally a node() builder or a plain config object — only a WorkflowBuilder or WorkflowJSON passes the shape guards.
  4. Verify isWorkflowBuilder/isWorkflowJSON expectations: a WorkflowJSON must have a top-level `nodes` array.

Example fix

// before
export default node('Http').parameters({ url: 'https://x' });

// after
export default workflow()
  .add(node('Http').parameters({ url: 'https://x' }));
Defensive patterns

Strategy: type-guard

Validate before calling

import { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';

function isWorkflowJSON(v: unknown): v is { nodes: unknown[] } {
  return typeof v === 'object' && v !== null && Array.isArray((v as { nodes?: unknown[] }).nodes);
}

// After interpretation, verify shape BEFORE calling asWorkflowBuilder
const result = interpretSDKCode(code, sdkFunctions);
if (!isWorkflowBuilder(result) && !isWorkflowJSON(result)) {
  throw new Error('Code must export a workflow built with the workflow() SDK function.');
}

Type guard

// Guard for the WorkflowJSON shape (has a nodes array)
function isWorkflowJSON(v: unknown): v is { nodes: unknown[]; connections?: unknown } {
  return typeof v === 'object' && v !== null && Array.isArray((v as { nodes?: unknown[] }).nodes);
}

// Guard for the WorkflowBuilder shape (duck-typed on .toJSON and .validate)
function isWorkflowBuilder(v: unknown): v is { toJSON: () => unknown; validate: () => unknown } {
  return typeof v === 'object' && v !== null
    && typeof (v as { toJSON?: unknown }).toJSON === 'function'
    && typeof (v as { validate?: unknown }).validate === 'function';
}

Try / catch

import { parseWorkflowCodeToBuilder } from '@n8n/workflow-sdk/codegen/parse-workflow-code';

try {
  const builder = parseWorkflowCodeToBuilder(code);
} catch (e) {
  if (e instanceof SyntaxError && /must export a workflow built with the workflow\(\) SDK function/.test(e.message)) {
    // instruct: wrap the export in workflow().add(...) or use workflow.fromJSON()
  }
  throw e;
}

Prevention

When it happens

Trigger: 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().

Common situations: 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).

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/2a3b722f4606a6a9. Report an issue: GitHub.