vitest-dev/vitest · error · Error
Unexpected empty queue
Error message
Unexpected empty queue
What it means
Internal assertion in BrowserPool.runNextTest: a file was just dequeued from this._queue, but this._promise is undefined. The promise is created at the start of runTests and is the resolve/reject handle for the whole batch; finding it absent while a file is being dispatched indicates the pool's internal state machine is inconsistent — treated as a framework bug.
Source
Thrown at packages/vitest/src/node/pools/browser.ts:370
const isolate = this.project.config.isolate
// we don't need to cleanup testers if isolation is enabled,
// because cleanup is done at the end of every test
if (isolate) {
this.finishSession(sessionId)
return
}
// we need to cleanup testers first because there is only
// one iframe and it does the cleanup only after everything is completed
const orchestrator = this.getOrchestrator(sessionId)
orchestrator.cleanupTesters()
.catch(error => this.reject(error))
.finally(() => this.finishSession(sessionId))
return
}
if (!this._promise) {
throw new Error(`Unexpected empty queue`)
}
const orchestrator = this.getOrchestrator(sessionId)
debug?.('[%s] run test %s', sessionId, file)
// warm the transform cache while the iframe is booting so the test
// file import doesn't wait for the transform; mirrors the URL the
// tester will request (see `importFile` in the browser runner)
const fileUrl = `/${/^\w:/.test(file.filepath) ? '@fs/' : ''}${file.filepath}`.replace(/\/+/g, '/')
void this.project.vite.transformRequest(fileUrl).catch(() => {})
this.setBreakpoint(sessionId, file.filepath).then(() => {
// this starts running tests inside the orchestrator
const testersPromise = this._traces.$(
`vitest.browser.run`,
{
context: this._otel.context,
attributes: {View on GitHub (pinned to d568f8ce37)
Solutions
- Report as a Vitest bug with a minimal browser test reproduction, focusing on cancel/re-run timing.
- Retry — if it was triggered by a one-off browser disconnect it often does not recur.
- Avoid triggering manual cancellation while browser tests are mid-run unless necessary.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await vitest.start()
} catch (e) {
if (e.message === 'Unexpected empty queue') {
console.error('Browser pool state race — retry; if persistent, report with reproduction.')
}
throw e
} Prevention
- Avoid manual cancellation while browser tests are mid-run unless necessary.
- Retry transient occurrences (often one-off disconnect-driven races).
- Pin a stable Vitest version; report persistent cases as bugs.
When it happens
Trigger: runNextTest is invoked (from a ready-session callback or page-ready callback) after the queue was already cleared/cancelled, so it shifts a file but the _promise was nulled by cancel()/reject()/finishSession at packages/vitest/src/node/pools/browser.ts:369-370.
Common situations: Cancellation racing with the run loop; a test completing and re-triggering runNextTest after the batch promise already resolved; browser disconnect during teardown.
Related errors
- The browser server was not initialized${project.name ? ` for
- Orchestrator not found for session ${sessionId}. This is a b
- Cannot find the environment. This is a bug in Vitest.
- Cannot set concurrency id because there are no valid free id
- Isolated tasks should not share runners
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/333057fc28cade12.json.
Report an issue: GitHub.