vitest-dev/vitest · error · Error
The child process was torn down or never initialized. This i
Error message
The child process was torn down or never initialized. This is a bug in Vitest.
What it means
Internal assertion in the forks worker: the private _fork getter throws if the underlying ChildProcess was never created (start() not called or failed) or was cleared (set to undefined after stop()). The getter is used by on/off/send, so any message interaction with a non-running forked process trips it.
Source
Thrown at packages/vitest/src/node/pools/workers/forksWorker.ts:108
fork.stdout?.unpipe(this.stdout)
this.stdout.setMaxListeners(this.stdout.getMaxListeners() - 1)
}
if (fork.stderr) {
fork.stderr?.unpipe(this.stderr)
this.stderr.setMaxListeners(this.stderr.getMaxListeners() - 1)
}
this._fork = undefined
}
deserialize(data: unknown): unknown {
return data
}
private get fork() {
if (!this._fork) {
throw new Error(`The child process was torn down or never initialized. This is a bug in Vitest.`)
}
return this._fork
}
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Report as a Vitest bug with reproduction (focus on cancellation/teardown timing).
- Retry — transient teardown races during Ctrl+C can surface this once.
- If using the @experimental ForksPoolWorker directly, never send before start() or after stop().
Defensive patterns
Strategy: try-catch
Try / catch
try {
await vitest.start()
} catch (e) {
if (e.message === 'The child process was torn down or never initialized. This is a bug in Vitest.') {
console.error('Forks worker teardown race — retry; if persistent, report as a bug.')
}
throw e
} Prevention
- Pin stable Vitest versions to avoid teardown/postMessage races.
- Retry transient occurrences during Ctrl+C cancellation.
- Never call ForksPoolWorker.send after stop() when using the experimental API.
When it happens
Trigger: ForksPoolWorker.on/off/send is called when this._fork is undefined — either before start() ran or after stop() set it to undefined at packages/vitest/src/node/pools/workers/forksWorker.ts:99-108. Indicates the runner sent a message to a torn-down worker.
Common situations: A race where the pool/runner posts a message after worker.stop() completed; stop() running during cancellation while a queued message is still in flight; a regression in PoolRunner.postMessage gating (it should drop messages when STOPPED).
Related errors
- The worker thread was torn down or never initialized. This i
- [vitest-pool-runner]: Cannot start a stopped runner
- Unexpected message ${JSON.stringify(message, null, 2)}
- Cannot find the environment. This is a bug in Vitest.
- The browser server was not initialized${project.name ? ` for
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/409372ccec371539.json.
Report an issue: GitHub.