vitest-dev/vitest · error · Error
Isolated tasks should not share runners
Error message
Isolated tasks should not share runners
What it means
Internal assertion in isEqualRunner (helper for Pool.getPoolRunner / shared runner reuse): the function is only ever called on the isolate:false reuse path, so receiving a task with task.isolate === true means the caller violated that contract. Isolated tasks must always get a fresh runner, never a reused shared one, so sharing one is rejected as a framework bug.
Source
Thrown at packages/vitest/src/node/pools/pool.ts:317
promise,
resolve,
reject: (reason: unknown) => {
resolver.isRejected = true
reject(reason)
},
isRejected: false,
}
return resolver
}
function formatFiles(task: PoolTask) {
return task.context.files.map(file => file.filepath).join(', ')
}
function isEqualRunner(runner: PoolRunner, task: PoolTask) {
if (task.isolate) {
throw new Error('Isolated tasks should not share runners')
}
if (runner.worker.name !== task.worker || runner.project !== task.project) {
return false
}
// by default, check that the environments are the same
// some workers (like vmThreads/vmForks) do not need this check
if (!runner.worker.canReuse) {
return isEnvironmentEqual(task.context.environment, runner.environment)
}
return runner.worker.canReuse(task)
}
function isEnvironmentEqual(env1: ContextTestEnvironment, env2: ContextTestEnvironment): boolean {
if (env1.name !== env2.name) {
return false
}
return deepEqual(env1.options, env2.options)
}View on GitHub (pinned to d568f8ce37)
Solutions
- Report as a Vitest bug with reproduction (isolate config + the failing specs).
- Avoid isolate:false if not needed to bypass the shared-runner path entirely.
- Check that no custom PoolWorker/PoolRunner logic mutates task.isolate between scheduling and reuse.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await vitest.start()
} catch (e) {
if (e.message === 'Isolated tasks should not share runners') {
console.error('Internal runner-reuse invariant violated — report as a Vitest bug.')
}
throw e
} Prevention
- Pin stable Vitest versions to avoid runner-reuse regressions.
- Avoid custom PoolWorker implementations that mutate task.isolate.
- Report with reproduction including isolate config and the failing specs.
When it happens
Trigger: isEqualRunner(runner, task) is called with task.isolate === true at packages/vitest/src/node/pools/pool.ts:315-317. The sharedRunners reuse path is gated on task.isolate === false upstream, so reaching the throw means that guard was bypassed.
Common situations: A regression in the isolate handling or sharedRunners logic; a custom worker whose canReuse/isolate contract is inconsistent; race during task reconfiguration.
Related errors
- Cannot set concurrency id because there are no valid free id
- Cannot find the environment. This is a bug in Vitest.
- The browser server was not initialized${project.name ? ` for
- Orchestrator not found for session ${sessionId}. This is a b
- Unexpected empty queue
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/9963778bc891c69f.json.
Report an issue: GitHub.