HarperFast / HarperFast/nextjs
Turbopack `next build` crashes with "Worker creator already registered" inside a Harper worker thread (server-side deploy fails on multi-thread clusters)
- Dominant language
- TypeScript
- Stars
- 4
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
## 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 `handleApplication` → `build()` → `withBuildLock` → `runNextBuild` → `next.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 : 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
- #52 concurrent-build race (fixed) — orthogonal; the lock works, the single build still crashes.
- #37 build-vs-RocksDB lock — notes "look into running nextjs builds in a worker thread"; that in-thread approach is what surfaces this crash.
- #51 Turbopack `import 'harper'` resolve.
Contributor guide
Research direction
Start with the build flow in dist/plugin.js, dist/buildLock.js, and the handleApplication → build() → withBuildLock → runNextBuild entry points described in the report. Reproduce with a replicated multi-node Harper cluster and a Next 16 app using the default Turbopack bundler. Done means the server-side build completes in a worker thread, writes .next/BUILD_ID, and serves GET / without the reported 404/500 failures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, react, typescript
- Domain
- backend, build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100