{"record":{"id":"1b13f77a73c6b93d","repo":"pydantic/monty","slug":"nodeworkerentry-must-run-as-a-worker-thread","errorCode":null,"errorMessage":"nodeWorkerEntry must run as a worker thread","messagePattern":"nodeWorkerEntry must run as a worker thread","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/monty-js/ts/worker/nodeWorkerEntry.ts","lineNumber":15,"sourceCode":"// Node `worker_threads` entry for a Monty worker.\n//\n// Runs in the worker thread and instantiates the precompiled component modules\n// passed through `workerData`. `WebAssembly.Module`s are structured-cloneable,\n// so each worker gets isolated state without recompiling. The browser entry\n// provides the same transport over `self.postMessage`.\n\nimport { parentPort, workerData } from 'node:worker_threads'\n\nimport type { ComponentModules } from './host.js'\nimport { serveDispatch } from './serve.js'\n\nvoid (async () => {\n  const port = parentPort\n  if (!port) throw new Error('nodeWorkerEntry must run as a worker thread')\n  const { modules } = workerData as { modules: ComponentModules }\n  await serveDispatch(\n    modules,\n    (reply) => port.postMessage(reply),\n    (handler) => port.on('message', handler),\n  )\n})()\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-js/ts/worker/nodeWorkerEntry.ts#L1-L23","documentation":"`nodeWorkerEntry.ts` is the bootstrap script for a `worker_threads` backend worker. It reads `parentPort` to communicate with the parent thread, and if it is undefined the script is not actually running inside a Node worker thread. The module then aborts immediately because there is no message channel to serve dispatch requests on.","triggerScenarios":"Executing `nodeWorkerEntry.ts` (or the compiled `nodeWorkerEntry.js`) directly with `node`, or passing it as an entry to something that runs it on the main thread, so `parentPort` is undefined.","commonSituations":"Hand-wiring a `worker_threads.Worker` without a proper entry wrapper, misconfiguring a bundler so the worker entry is inlined into the main bundle, or debugging the worker file by running it standalone.","solutions":["Run the worker via `new Worker(new URL('./nodeWorkerEntry.js', import.meta.url))` (or the library's `nodeFactory`) so Node creates a real `parentPort`.","If wiring workers manually, pass `{ workerData: { modules } }` and only from code that itself runs inside a `Worker`, never on the main thread.","Check bundler config: the worker entry must be emitted as a separate chunk, not inlined into the main bundle."],"exampleFix":"// before\nnode ./dist/worker/nodeWorkerEntry.js   // main thread -> no parentPort\n\n// after\nimport { Worker } from 'node:worker_threads'\nconst w = new Worker(new URL('./dist/worker/nodeWorkerEntry.js', import.meta.url), { workerData: { modules } })","handlingStrategy":"validation","validationCode":"import { parentPort } from 'node:worker_threads'\nif (!parentPort) throw new Error('nodeWorkerEntry must be launched inside a worker_threads Worker')","typeGuard":"function inWorkerThread(): boolean { return parentPort != null }","tryCatchPattern":"try {\n  void bootstrap()\n} catch (err) {\n  console.error('worker bootstrap failed:', err)\n  process.exitCode = 1\n}","preventionTips":["Only launch the entry via new Worker(...), never with node directly.","Pass workerData { modules } when constructing the Worker.","Ensure bundlers emit the worker entry as a separate chunk.","Test the worker bootstrap in CI with a real worker_threads instantiation."],"tags":["node","worker-threads","wasm-worker","misconfiguration"],"backgroundTag":"invalid-state-transition","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}