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(
filenamesView on GitHub (pinned to d568f8ce37)
Solutions
- Ensure startCoverage() runs and succeeds before takeCoverage() is called in the same module instance.
- Avoid invoking takeCoverage after stopCoverage has disconnected the session.
- 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
- Always pair startCoverage with takeCoverage in the same lifecycle.
- Never call takeCoverage after stopCoverage in one process.
- Verify node:inspector is available in the target runtime before relying on v8 coverage.
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
- Something removed the coverage directory "${coverageFilesDir
- "Istanbul" coverage provider is not compatible with "experim
- @vitest/coverage-v8 does not work with ${browserConfig} Use
- Failed to load ${CoverageProviderMap[provider]}. Default exp
- Page "${sessionId}" not found in ${this.browserName} browser
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/59dc69706213c4cb.json.
Report an issue: GitHub.