vitest-dev/vitest · error · Error
process.exit unexpectedly called with
Error message
process.exit unexpectedly called with "${code}" What it means
Identical override to error [366] but installed in the vm worker setup path (runtime/workers/vm.ts). Vitest reassigns process.exit in the vm worker so that code under test calling process.exit(code) throws instead of killing the vm worker, preserving worker/caches for subsequent test files.
Solutions
- Spy on process.exit in the test: vi.spyOn(process, 'exit').mockImplementation(() => { throw new Error('exit') }).
- Refactor code under test to throw instead of process.exit.
- Inject a callback/hook the code calls instead of process.exit.
- Run the exiting path in a child process if real exit semantics are required.
Example fix
// before: under test
if (!cfg) process.exit(1)
// after: test spies on exit
vi.spyOn(process, 'exit').mockImplementation(c => { throw new Error('exit ' + c) })
expect(() => run()).toThrow('exit 1') Defensive patterns
Strategy: validation
Validate before calling
import { vi } from 'vitest'
beforeEach(() => {
vi.spyOn(process, 'exit').mockImplementation((c) => { throw new Error(`exit ${c}`) })
}) Try / catch
try {
runUnderVm()
} catch (e) {
if (/process\.exit unexpectedly called/.test(e.message)) {
// assert exit code; the worker stays alive
} else throw e
} Prevention
- Refactor process.exit calls to thrown errors in code under test.
- Spy on process.exit when testing error paths under the vm pool.
- Run exiting code in a subprocess when real exit is needed.
When it happens
Trigger: Application code or a dependency invoked inside the vm context calls process.exit(). Because the vm worker overrides process.exit to throw, the call surfaces as 'process.exit unexpectedly called with "<code>"'.
Common situations: Same as [366]: testing a CLI/library that hard-exits on errors, a dependency exiting on missing config, or test helpers using process.exit, now exercised under the vm pool.
Related errors
- process.exit unexpectedly called with
- Cannot import " ": its vm context was torn down.
- Cannot import " ": the test context was torn down.
- Browser is not initialized
- Browser provider is not defined for the project
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/e9fc5fb19750469d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/workers/vm.ts:122
// TODO: don't hardcode setImmediate in fake timers defaults
context.setImmediate = setImmediate
context.clearImmediate = clearImmediate
const stubs = getDefaultRequestStubs(context)
const externalModulesExecutor = new ExternalModulesExecutor({
context,
fileMap,
codeCache,
resolveCache,
moduleInfoCache,
packageCache,
transform: rpc.transform,
viteClientModule: stubs['/@vite/client'],
})
process.exit = (code = process.exitCode || 0): never => {
throw new Error(`process.exit unexpectedly called with "${code}"`)
}
listenForErrors(() => state)
const moduleRunner = startVitestModuleRunner({
context,
evaluatedModules: state.evaluatedModules,
state,
externalModulesExecutor,
createImportMeta: createNodeImportMeta,
traces,
})
emitModuleRunner(moduleRunner as any)
Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
value: {
context,View on GitHub (pinned to 1fa9837ec2)