diff --git a/.changeset/fix-next-build-stale-socket.md b/.changeset/fix-next-build-stale-socket.md new file mode 100644 index 0000000000..c3fd808f2d --- /dev/null +++ b/.changeset/fix-next-build-stale-socket.md @@ -0,0 +1,7 @@ +--- +"@workflow/next": patch +--- + +fix(next): guard socket-info filesystem fallback behind lazy discovery flag + +Prevents `ECONNREFUSED` during `next build` when a stale `workflow-socket.json` file exists from a previous `next dev` session. diff --git a/.changeset/fix-step-bundle-dynamic-imports.md b/.changeset/fix-step-bundle-dynamic-imports.md new file mode 100644 index 0000000000..d080230c46 --- /dev/null +++ b/.changeset/fix-step-bundle-dynamic-imports.md @@ -0,0 +1,7 @@ +--- +"@workflow/builders": patch +--- + +fix(builders): add `webpackIgnore` comments to dynamic imports in generated step bundle + +Prevents Turbopack/webpack "Module not found" errors for runtime-resolved dynamic `import()` calls (e.g. from `@vercel/queue`) that are inlined into the step route bundle. diff --git a/packages/builders/src/base-builder.ts b/packages/builders/src/base-builder.ts index 25762fa47a..9b2e290768 100644 --- a/packages/builders/src/base-builder.ts +++ b/packages/builders/src/base-builder.ts @@ -589,6 +589,22 @@ export abstract class BaseBuilder { const stepsResult = await esbuildCtx.rebuild(); + // Post-process the generated step bundle to add bundler-ignore comments + // to dynamic `import()` calls with non-literal arguments (e.g. variables, + // expressions). These dynamic imports are resolved at runtime and should + // not be traced by downstream bundlers like Turbopack/webpack, which would + // otherwise emit "Module not found" errors for unresolvable paths. + if (outfile) { + const bundleContent = await readFile(outfile, 'utf8'); + const processed = bundleContent.replace( + /\bimport\((?!\s*["'`])/g, + 'import(/* webpackIgnore: true */ ' + ); + if (processed !== bundleContent) { + await writeFile(outfile, processed); + } + } + this.logEsbuildMessages(stepsResult, 'steps bundle creation'); this.logBaseBuilderInfo( 'Created steps bundle', diff --git a/packages/next/src/loader.ts b/packages/next/src/loader.ts index e04a2b219e..dde704b2e7 100644 --- a/packages/next/src/loader.ts +++ b/packages/next/src/loader.ts @@ -178,6 +178,14 @@ function getSocketInfoFilePath(): string | null { return configuredPath; } + // Only fall back to filesystem discovery when deferred (lazy) discovery is + // active. Without this guard, a stale socket-info file left behind by a + // previous `next dev` session causes ECONNREFUSED during eager builds + // (i.e. `next build` without `lazyDiscovery`). + if (process.env.WORKFLOW_NEXT_LAZY_DISCOVERY !== '1') { + return null; + } + // Fallback for worker processes that don't inherit dynamic env updates // from the process that created the socket server. const distDir = process.env.WORKFLOW_NEXT_DIST_DIR || '.next';