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

  1. Report as a Vitest bug with reproduction (isolate config + the failing specs).
  2. Avoid isolate:false if not needed to bypass the shared-runner path entirely.
  3. 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

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


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/9963778bc891c69f.json. Report an issue: GitHub.