workflow
Version:
Workflow SDK - Build durable, resilient, and observable workflows
137 lines (100 loc) • 5.05 kB
text/mdx
---
title: start-invalid-workflow-function
description: The function passed to start() must be a transformed workflow function.
type: troubleshooting
summary: Fix invalid workflow function errors by adding "use workflow" and enabling your framework integration.
prerequisites:
- /docs/foundations/starting-workflows
related:
- /docs/api-reference/workflow-api/start
- /docs/getting-started/next
- /docs/api-reference/workflow-next/with-workflow
---
<CopyPrompt
text="Fix `start()` receiving an invalid workflow function. Find the function passed to `start()` from `workflow/api`. Ensure the target function is directly imported, exported from its workflow file, and contains the literal `"use workflow"` directive at the top of the function body. Do not pass wrapper callbacks like `start(async () => workflowFn())`; call `start(workflowFn, [args])`. Verify the framework integration is configured (`withWorkflow()` in Next.js, `workflow()`/`workflowPlugin()` in Vite/Astro/SvelteKit, `workflow/nitro`, `workflow/nuxt`, or `@workflow/nest` as appropriate) and that the workflow file is inside a transformed directory. Add a local route/test that calls `start(workflowFn, args)` and confirms a run is created."
/>
This error occurs when `start()` receives a function that does not have Workflow SDK'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
```text
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
```
## Why this happens
`start()` expects an imported workflow function rather than any async function. During compilation, Workflow SDK 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"`
{/* @skip-typecheck: incomplete code sample */}
```typescript lineNumbers
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.
{/* @skip-typecheck: incomplete code sample */}
```typescript lineNumbers
import { start } from "workflow/api";
export async function sendReminder(email: string) {
"use workflow"; // [!code highlight]
await sendEmail(email);
}
export async function POST() {
await start(sendReminder, ["hello@example.com"]); // [!code highlight]
return new Response("ok");
}
async function sendEmail(email: string) {
"use step";
console.log(`Sending email to ${email}`);
}
```
### Missing `withWorkflow()` in `next.config.ts`
{/* @skip-typecheck: incomplete code sample */}
```typescript title="next.config.ts" lineNumbers
import type { NextConfig } from "next";
const nextConfig: NextConfig = {};
export default nextConfig;
```
**Fix:** Wrap the config with `withWorkflow()` so workflow files are transformed.
```typescript title="next.config.ts" lineNumbers
import type { NextConfig } from "next";
import { withWorkflow } from "workflow/next"; // [!code highlight]
const nextConfig: NextConfig = {};
export default withWorkflow(nextConfig); // [!code highlight]
```
### Passing a wrapper function instead of the imported workflow
{/* @skip-typecheck: incomplete code sample */}
```typescript lineNumbers
import { start } from "workflow/api";
import { sendReminder } from "./workflows/send-reminder";
export async function POST() {
// Does NOT work
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.
```typescript lineNumbers
import { start } from "workflow/api";
import { sendReminder } from "./workflows/send-reminder";
export async function POST() {
await start(sendReminder, ["hello@example.com"]); // [!code highlight]
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()`](/docs/api-reference/workflow-next/with-workflow)).
3. Pass the imported workflow function directly to `start()`, not a wrapper callback.
4. Keep the function in a file that goes through Workflow SDK's transform step.
## Related
- [`start()`](/docs/api-reference/workflow-api/start)
- [`withWorkflow()`](/docs/api-reference/workflow-next/with-workflow)
- [Next.js Getting Started](/docs/getting-started/next)