Skip to content

Turbopack next build crashes with "Worker creator already registered" inside a Harper worker thread (server-side deploy fails on multi-thread clusters) #57

Description

@dawsontoth

Summary

On a real (multi-thread, replicated) Harper cluster, the on-startup production build fails immediately for Turbopack (the Next.js 16 default bundler). next build throws uncaughtException: Worker creator already registered { code: 'GenericFailure' } the instant it runs inside a Harper worker thread. The build aborts before writing .next/BUILD_ID, so the app never serves.

This is distinct from #52 (the concurrent-build race, now fixed). withBuildLock correctly serializes to a single builder — that one builder still crashes.

Environment

  • Harper (harper-pro) 5.1.23, multi-node replicated cluster (~8 http worker threads/node)
  • @harperfast/nextjs 2.2.3
  • next 16.2.11, React 19 (App Router)
  • Bundler: Turbopack (Next 16 default; config.bundler unset)

What happens

On component load, each worker runs handleApplicationbuild()withBuildLockrunNextBuildnext.build(...). The winning builder crashes:

uncaughtException Error: Worker creator already registered  { code: 'GenericFailure' }
process.exit(1) called in worker thread N — ignored to keep Harper alive.
  at printAndExit (next/dist/server/lib/utils.js:75)
  at next/dist/cli/next-build.js:106
  at runNextBuild (@harperfast/nextjs/dist/plugin.js:247)
  at withBuildLock (@harperfast/nextjs/dist/buildLock.js:117)
  at build (@harperfast/nextjs/dist/plugin.js:214)
  at handleApplication (@harperfast/nextjs/dist/plugin.js:191)
Error building Next.js application <app>: ENOENT: no such file or directory, open '.../.next/BUILD_ID'

Downstream symptoms depend on the thread:

  • The builder thread returns from handleApplication without serving → GET / is 404.
  • Sibling threads that skip-on-failure in withBuildLock then reach serve() with no .next → Next throws 500 "Could not find a production build in the '.next' directory".

Root cause (hypothesis)

Turbopack (Rust/napi) registers its own native "worker creator" when it spins up build workers. Running that inside a Harper worker thread — where Harper has already registered a worker creator — is a double registration → GenericFailure. next's global uncaught-exception listener then calls process.exit(1), which Harper's workerProcessGuard swallows to stay alive, leaving a half-run build with no BUILD_ID.

This is the same class of failure as the historical Harper 5.0.15 "Worker creator already registered" on Next 16 turbopack builds; it is not resolved by 5.1.22/5.1.23.

Why it isn't caught locally / in CI

A plain next build from the CLI runs as an ordinary process (not inside a Harper worker thread) and succeeds in ~850 ms. Local harper run/harper dev and small CI runners (1–2 worker threads) don't reproduce the crash — only a real multi-thread cluster does.

Reproduce

  1. Scaffold a minimal Next.js 16 app with withHarper() and the @harperfast/nextjs component (no prebuilt, no bundler override).
  2. harper deploy_component . restart=true replicated=true to a multi-node cluster.
  3. GET / → 404/500; system log shows the crash above.

Impact

The plugin's advertised "Harper builds your app on the server, no local build required" model does not work on a cluster with Turbopack. This blocks server-side-build deploys for Next 16 (default bundler).

Workarounds

  • prebuilt: true — build .next locally and ship it; the plugin skips building and serves it. Verified working on 5.1.23 (serves + server-action write path commits/persists across the replicated cluster).
  • bundler: webpack avoids this crash but hits a separate wall — the build exceeds the 30 s handleApplication budget (filed separately).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions