{"record":{"id":"409372ccec371539","repo":"vitest-dev/vitest","slug":"the-child-process-was-torn-down-or-never-initializ","errorCode":null,"errorMessage":"The child process was torn down or never initialized. This is a bug in Vitest.","messagePattern":"The child process was torn down or never initialized\\. This is a bug in Vitest\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/pools/workers/forksWorker.ts","lineNumber":113,"sourceCode":"      this.stdout.setMaxListeners(this.stdout.getMaxListeners() - 1)\n    }\n\n    if (fork.stderr) {\n      await streamFlushed(fork.stderr)\n      fork.stderr.unpipe(this.stderr)\n      this.stderr.setMaxListeners(this.stderr.getMaxListeners() - 1)\n    }\n\n    this._fork = undefined\n  }\n\n  deserialize(data: unknown): unknown {\n    return data\n  }\n\n  private get fork() {\n    if (!this._fork) {\n      throw new Error(`The child process was torn down or never initialized. This is a bug in Vitest.`)\n    }\n    return this._fork\n  }\n}\n","sourceCodeStart":95,"sourceCodeEnd":118,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/node/pools/workers/forksWorker.ts#L95-L118","documentation":"The forksWorker 'fork' getter throws when this._fork is undefined, meaning the child process was either never spawned or has already been closed/torn down. Any later operation that dereferences 'fork' (send, kill, pipe) hits this guard. Marked as a bug in Vitest because the worker should not be used after teardown.","triggerScenarios":"A method on forksWorker accesses the 'fork' property after close()/teardown set this._fork = undefined, or before the fork was successfully created.","commonSituations":"A race where a message is sent to a worker that is shutting down, a forced teardown during an interrupt (Ctrl-C), an error in pool lifecycle that reuses a disposed worker, or a worker crash followed by a delayed send.","solutions":["Check pool/worker lifecycle logs for the original teardown cause that preceded this access.","Ensure you are not manually reusing a closed worker or pool.","Update Vitest - many of these races are fixed in newer releases.","If reproducible, capture the sequence of pool events and file a Vitest issue."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Check the worker is alive before sending.\nfunction isWorkerAlive(worker: { _fork?: unknown }): boolean {\n  return Boolean(worker._fork)\n}","typeGuard":"const isForkAlive = (worker: { _fork?: unknown }): worker is { _fork: object } => Boolean(worker._fork)","tryCatchPattern":"try {\n  worker.send(msg)\n} catch (err) {\n  if (err instanceof Error && err.message.includes('torn down')) {\n  // worker disposed; recreate or skip\n  return\n  }\n  throw err\n}","preventionTips":["Never reuse a pool/worker after close()/teardown.","Track worker lifecycle state explicitly before sending.","Handle SIGINT cleanly to avoid late sends during teardown."],"tags":["internal-bug","worker-pool","forks","lifecycle","race"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}