vitest-dev/vitest · error · Error

V8 provider missing inspector session.

Error message

V8 provider missing inspector session.

What it means

Thrown during takeCoverage() in the V8 node-side coverage module when this.session is null/undefined. Coverage collection relies on a node:inspector Session to call Profiler.takePreciseCoverage; if the session was never created (startCoverage not called or failed) there is nothing to query.

Source

Thrown at packages/coverage-v8/src/index.ts:54

    }

    this.session ||= new inspector.Session()
    const session = this.session as inspector.Session

    session.connect()
    await session.post('Profiler.enable')
    await session.post('Profiler.startPreciseCoverage', { callCount: true, detailed: true })
  },

  async takeCoverage(options): Promise<string | undefined> {
    if (provider === 'stackblitz') {
      return
    }

    const session = this.session as inspector.Session

    if (!session) {
      throw new Error('V8 provider missing inspector session.')
    }

    const coverage = await session.post('Profiler.takePreciseCoverage')
    const result: ScriptCoverageWithOffset[] = []

    // Reduce amount of data sent over rpc by doing some early result filtering
    for (const entry of coverage.result as ScriptCoverageWithOffset[]) {
      if (filterResult(entry)) {
        entry.startOffset = options?.moduleExecutionInfo?.get(normalize(fileURLToPath(entry.url)))?.startOffset || 0

        result.push(entry)
      }
    }

    if (this.extendedContextCoverageDir && existsSync(this.extendedContextCoverageDir)) {
      const filenames = await readdir(this.extendedContextCoverageDir)
      const contents = await Promise.all(
        filenames

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Ensure startCoverage() runs and succeeds before takeCoverage() is called in the same module instance.
  2. Avoid invoking takeCoverage after stopCoverage has disconnected the session.
  3. If the runtime blocks node:inspector, switch to a supported Node version or the istanbul provider.

Example fix

// before
await mod.stopCoverage({ isolate: true })
await mod.takeCoverage({}) // session is now null
// after
await mod.startCoverage({ isolate: true, reportsDirectory })
await mod.takeCoverage({ coverageFilesDirectory })
await mod.stopCoverage({ isolate: true })
Defensive patterns

Strategy: validation

Validate before calling

// guard before taking coverage
const session = (mod as any).session
if (!session) {
  throw new Error('Call startCoverage() before takeCoverage()')
}
await mod.takeCoverage(opts)

Type guard

function hasSession(mod: any): mod is { session: NonNullable<unknown> } {
  return mod.session != null
}

Try / catch

try {
  await mod.takeCoverage(opts)
} catch (e) {
  if (/missing inspector session/i.test(String((e as Error).message))) {
    await mod.startCoverage(opts)
    return mod.takeCoverage(opts)
  }
  throw e
}

Prevention

When it happens

Trigger: takeCoverage() is invoked before startCoverage() successfully created and connected the inspector session, or this.session was reset to null by a prior stopCoverage().

Common situations: Coverage taken in a context where the V8 profiler couldn't start (e.g. incompatible runtime, inspector disabled); calling takeCoverage after stopCoverage in the same process; running under a worker that didn't inherit the session setup.

Related errors


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