start-invalid-workflow-function

The function passed to start() must be a transformed workflow function.

This error occurs when start() receives a function that does not have Workflow DevKit's generated workflow metadata. In practice, that usually means the function is missing "use workflow" or the file was never transformed by your framework integration.

Error Message

'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.

Why This Happens

start() expects an imported workflow function, not just any async function. During compilation, Workflow DevKit transforms files that contain "use workflow" and attaches generated metadata such as the workflow ID. If that transform never runs, or if you pass a wrapper function instead of the transformed export, start() cannot identify what to enqueue and throws this error.

Common Causes

Missing "use workflow"

import { start } from "workflow/api";

export async function sendReminder(email: string) {
  await sendEmail(email);
}

export async function POST() {
  await start(sendReminder, ["hello@example.com"]);
  return new Response("ok");
}

async function sendEmail(email: string) {
  "use step";
  console.log(`Sending email to ${email}`);
}

Fix: Add "use workflow" to the workflow function.

import { start } from "workflow/api";

export async function sendReminder(email: string) {
  "use workflow"; 
  await sendEmail(email);
}

export async function POST() {
  await start(sendReminder, ["hello@example.com"]); 
  return new Response("ok");
}

async function sendEmail(email: string) {
  "use step";
  console.log(`Sending email to ${email}`);
}

Missing withWorkflow() in next.config.ts

next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {};

export default nextConfig;

Fix: Wrap the config with withWorkflow() so workflow files are transformed.

next.config.ts
import type { NextConfig } from "next";
import { withWorkflow } from "workflow/next"; 

const nextConfig: NextConfig = {};

export default withWorkflow(nextConfig); 

Passing a wrapper function instead of the imported workflow

import { start } from "workflow/api";
import { sendReminder } from "./workflows/send-reminder";

export async function POST() {
  await start(async () => sendReminder("hello@example.com"));
  return new Response("ok");
}

Fix: Pass the imported workflow function directly and provide arguments in the second parameter.

import { start } from "workflow/api";
import { sendReminder } from "./workflows/send-reminder";

export async function POST() {
  await start(sendReminder, ["hello@example.com"]); 
  return new Response("ok");
}

Checklist

Before calling start():

  1. Confirm the function includes "use workflow" as its first statement.
  2. Confirm your framework integration is enabled (for Next.js, wrap next.config.ts with withWorkflow()).
  3. Pass the imported workflow function directly to start(), not a wrapper callback.
  4. Keep the function in a file that goes through Workflow DevKit's transform step.