Skip to content

fix: load harper lazily in CacheHandler to avoid worker conflicts#47

Merged
jjohnson-hdb merged 1 commit into
mainfrom
fix/cachehandler-lazy-load
May 12, 2026
Merged

fix: load harper lazily in CacheHandler to avoid worker conflicts#47
jjohnson-hdb merged 1 commit into
mainfrom
fix/cachehandler-lazy-load

Conversation

@jjohnson-hdb
Copy link
Copy Markdown
Contributor

The Next.js cacheHandler module is loaded by Next.js itself (via require() on the cacheHandler config path), not by Harper. With turbopack, that load happens inside a build worker thread. Importing harper at the top of CacheHandler.cts ran harper's module initialization in that worker thread, which tried to register native worker hooks process-wide — conflicting with the same registration already done by the Harper main process. The result was a stream of "Worker creator already registered" uncaught exceptions; the HTTP worker kept restarting until Harper gave up
(Thread has been restarted undefined times and will not be restarted).

Same load path also fires with webpack — Next.js's build init requires the cacheHandler path directly via Node's require(), which bypasses webpack externals and serverExternalPackages. With harper not present in the customer's node_modules, the build fails with MODULE_NOT_FOUND on node_modules/@harperfast/nextjs/node_modules/harper.

Switch to the same pattern plugin.ts uses: import harper for types only, and read databases from globalThis at call time. The module now loads cleanly in any context, and methods short-circuit (return null / no-op) if databases isn't available — which is the correct fallback when there is no Harper runtime to talk to.

The Next.js cacheHandler module is loaded by Next.js itself (via
`require()` on the `cacheHandler` config path), not by Harper. With
turbopack, that load happens inside a build worker thread. Importing
`harper` at the top of CacheHandler.cts ran harper's module
initialization in that worker thread, which tried to register native
worker hooks process-wide — conflicting with the same registration
already done by the Harper main process. The result was a stream of
"Worker creator already registered" uncaught exceptions; the HTTP
worker kept restarting until Harper gave up
(`Thread has been restarted undefined times and will not be restarted`).

Same load path also fires with webpack — Next.js's build init requires
the cacheHandler path directly via Node's `require()`, which bypasses
webpack `externals` and `serverExternalPackages`. With `harper` not
present in the customer's node_modules, the build fails with
MODULE_NOT_FOUND on `node_modules/@harperfast/nextjs/node_modules/harper`.

Switch to the same pattern `plugin.ts` uses: import `harper` for types
only, and read `databases` from `globalThis` at call time. The module
now loads cleanly in any context, and methods short-circuit (return
null / no-op) if `databases` isn't available — which is the correct
fallback when there is no Harper runtime to talk to.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jjohnson-hdb jjohnson-hdb merged commit 477290e into main May 12, 2026
6 checks passed
@jjohnson-hdb jjohnson-hdb deleted the fix/cachehandler-lazy-load branch May 12, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant