-
Notifications
You must be signed in to change notification settings - Fork 151
Open
Description
Calling a step from outside a workflow or from another step will essentially run the step in the same process like a normal function (in other words, the use step directive is a no-op). This means you can reuse step functions in other parts of your codebase without needing to duplicate business logic.
Unfortunately it seems that there's a bug that creates "Referrence Error: <non-step dependency> is not defined" when attempting to use any variable or functions not coloured with use-step
A minimal reproduction can be found below:
Minimal reproduction
https://github.com/remiconnesson/useworfklow-rsc-maybe-hoisting-issue-repro
Given those files
Please notice the function below doesnt have "use step" directive
// <file path="utils/dummy-util.ts">
export async function dummyUtil(data: unknown) {
return data;
}// <file path="app/workflows/step.ts">
import { dummyUtil } from "@/utils/dummy-util";
// This function succeeds when called in a workflow file but will crash when called outside of a workflow
export async function dummyStep() {
"use step";
const data = dummyUtil({ id: crypto.randomUUID() }); // <-- ❌ will crash when the step is called outside of a workflow : `ReferenceError: dummyUtil is not defined`
console.log(data);
return data;
}// <file path="app/workflows/workflow.ts">
import { dummyStep } from "./step";
export async function dummyWorkflow() {
"use workflow";
const data = await dummyStep(); // <-- ✅ no issue when used inside a workflow
return data
}When called in an API endpoint
// app/api/dummy/route.ts
import { NextResponse } from "next/server";
import { start } from "workflow/api";
import { dummyStep } from "@/app/workflows/step";
import { dummyWorkflow } from "@/app/workflows/workflow";
export async function GET() {
const run = await start(dummyWorkflow); // <-- This works, and the workflow completes properly ✅
const runData = await run.returnValue
console.log("endpoint.1 :", runData)
const data = await dummyStep(); // <-- this crashes ❌
return NextResponse.json({
runData,
data,
});
}we get the following logs on vercel world
2025-12-16 16:17:04.303 [info] endpoint.1: { id: 'f9dad572-c66a-41f7-a4de-d847791f0f91' }
2025-12-16 16:17:04.309 [error] ReferenceError: dummyUtil is not defined
at R (.next/server/chunks/[root-of-the-server]__d2b94b46._.js:1:4565)
at E (.next/server/chunks/[root-of-the-server]__d2b94b46._.js:1:4900)
at async l (.next/server/chunks/[root-of-the-server]__d2b94b46._.js:1:8109)
at async d (.next/server/chunks/[root-of-the-server]__d2b94b46._.js:1:9147)
at async A (.next/server/chunks/[root-of-the-server]__d2b94b46._.js:1:10225)
and the following logs on local world
endpoint.1: { id: 'c1aca253-0e18-4430-a11e-7468a344862f' }
ReferenceError: dummyUtil is not defined
at dummyStep (app/workflows/step.ts:3:18)
at GET (app/api/dummy-endpoint/route.ts:13:31)
1 | /**__internal_workflows{"steps":{"app/workflows/step.ts":{"dummyStep":{"stepId":"step//app/workflows/step.ts//dummyStep"}}}}*/;
2 | export async function dummyStep() {
> 3 | const data = dummyUtil({
| ^
4 | id: crypto.randomUUID()
5 | });
6 | console.log(data);
GET /api/dummy-endpoint 500 in 1096ms (compile: 8ms, render: 1088ms)
Metadata
Metadata
Assignees
Labels
No labels