vitest-dev/vitest · error · Error

The child process was torn down or never initialized. This…

Error message

The child process was torn down or never initialized. This is a bug in Vitest.

What it means

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.

Solutions

  1. Check pool/worker lifecycle logs for the original teardown cause that preceded this access.
  2. Ensure you are not manually reusing a closed worker or pool.
  3. Update Vitest - many of these races are fixed in newer releases.
  4. If reproducible, capture the sequence of pool events and file a Vitest issue.
Defensive patterns

Strategy: type-guard

Validate before calling

// Check the worker is alive before sending.
function isWorkerAlive(worker: { _fork?: unknown }): boolean {
  return Boolean(worker._fork)
}

Type guard

const isForkAlive = (worker: { _fork?: unknown }): worker is { _fork: object } => Boolean(worker._fork)

Try / catch

try {
  worker.send(msg)
} catch (err) {
  if (err instanceof Error && err.message.includes('torn down')) {
  // worker disposed; recreate or skip
  return
  }
  throw err
}

Prevention

When it happens

Trigger: A method on forksWorker accesses the 'fork' property after close()/teardown set this._fork = undefined, or before the fork was successfully created.

Common situations: 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.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/409372ccec371539. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/node/pools/workers/forksWorker.ts:113

      this.stdout.setMaxListeners(this.stdout.getMaxListeners() - 1)
    }

    if (fork.stderr) {
      await streamFlushed(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 1fa9837ec2)