Skip to content

Can't call a step function outside of a workflow if that functions uses dependencies not marked with "use step" #630

@remiconnesson

Description

@remiconnesson

The docs mention:

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions