Skip to content

Workflow execution fails in dev when running nitro on port other than 3000 #236

@benjamincburns

Description

@benjamincburns

When trying the nitro quickstart I had another server listening on port 3000 already, so nitro dev started up on port 3001.

When I ran curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3001/api/signup it returned a 200 status and the expected response, but then I got the first error below in the nitro logs.

I then stopped my other server process and restarted nitro dev so it could listen on port 3000, and the quickstart workflow ran as expected.

Just to troubleshoot I also tried forcing it to run on port 3001 by running nitro dev --port 3001, and I got the second error below (ECONNREFUSED).

First error - caused by port conflict on start of nitro dev:

[embedded world] Failed to queue message {
  queueName: '__wkf_workflow_workflow//workflows/user-signup.ts//handleUserSignup',
  text: '{"message":"Route POST:/.well-known/workflow/v1/flow not found","error":"Not Found","statusCode":404}',
  status: 404,
  headers: {
    'access-control-allow-credentials': 'true',
    'access-control-allow-origin': 'http://localhost:3000/',
    connection: 'keep-alive',
    'content-length': '101',
    'content-type': 'application/json; charset=utf-8',
    date: 'Thu, 06 Nov 2025 01:24:33 GMT',
    'keep-alive': 'timeout=72'
  },
  body: '{"runId":"wrun_01K9BC7WNWSZP85QN1G7V4110A","traceCarrier":{}}'
}
< same error repeats two more times >
[embedded world] Reached max retries of embedded world queue implementation

Second error - caused by running nitro dev --port 3001:

[unhandledRejection] TypeError: fetch failed
    at node:internal/deps/undici/undici:15845:13
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async file:///path/to/my/project/node_modules/@workflow/world-local/dist/queue.js:54:34 {
  [cause]: AggregateError [ECONNREFUSED]:
      at internalConnectMultiple (node:net:1134:18)
      at afterConnectMultiple (node:net:1715:7) {
    code: 'ECONNREFUSED',
    [errors]: [ [Error], [Error] ]
  }
}

MRE (it's just the quickstart code):

workflows/user-signup.ts:

import { FatalError, sleep } from "workflow";

export async function handleUserSignup(email: string) {
  "use workflow"; 

  const user = await createUser(email);
  await sendWelcomeEmail(user);

  await sleep("5s"); // Pause for 5s - doesn't consume any resources
  await sendOnboardingEmail(user);

  return { userId: user.id, status: "onboarded" };
}

export async function createUser(email: string) {
  "use step"; 
  console.log(`Creating user with email: ${email}`);
  // Full Node.js access - database calls, APIs, etc.
  return { id: crypto.randomUUID(), email };
}

export async function sendOnboardingEmail(user: { id: string; email: string }) {
  "use step"; 
  if (!user.email.includes("@")) {
    // To skip retrying, throw a FatalError instead
    throw new FatalError("Invalid Email");
  }
  console.log(`Sending onboarding email to user: ${user.id}`);
}

export async function sendWelcomeEmail(user: { id: string; email: string }) {
  "use step"; 
  console.log(`Sending welcome email to user: ${user.id}`);
  if (Math.random() < 0.3) {
    // By default, steps will be retried for unhandled errors
    throw new Error("Retryable!");
  }
}

server/api/signup.post.ts:

import { start } from 'workflow/api';
import { defineEventHandler, readBody } from 'h3';
import { handleUserSignup } from "../../workflows/user-signup";

export default defineEventHandler(async (event) => {
  const { email } = await readBody(event);

  // Executes asynchronously and doesn't block your app
  await start(handleUserSignup, [email]);

  return Response.json({
    message: "User signup workflow started",
  });
});

nitro.config.ts:

import { defineNitroConfig } from "nitropack/config"

// https://nitro.build/config
export default defineNitroConfig({
  compatibilityDate: "latest",
  srcDir: "server",
  modules: ["workflow/nitro"],
});

package.json:

{
  "name": "nitro-app",
  "private": true,
  "scripts": {
    "build": "nitro build",
    "dev": "nitro dev",
    "preview": "node .output/server/index.mjs"
  },
  "devDependencies": {
    "h3": "^1.15.4",
    "nitropack": "^2.12.4"
  },
  "dependencies": {
    "workflow": "^4.0.1-beta.11"
  }
}

Metadata

Metadata

Assignees

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