vitest-dev/vitest · error · Error
vitest/browser can be imported only inside the Browser Mode.
Error message
vitest/browser can be imported only inside the Browser Mode. ${pool ? `Your test is running in ${pool} pool. Make sure your regular tests are excluded from the "test.include" glob pattern.` : 'Instead, it was imported outside of Vitest.'} What it means
Thrown at module load time by the fallback vitest/browser module (packages/browser/context.js). The real vitest/browser is a virtual module injected only when a test runs in Browser Mode (browser pool). This stub is what Node resolves when something imports vitest/browser from a normal (non-browser) Vitest run, and it throws immediately with a hint about the active pool.
Source
Thrown at packages/browser/context.js:14
// Vitest resolves "vitest/browser" as a virtual module instead
// fake exports for static analysis
export const page = null
export const server = null
export const userEvent = null
export const cdp = null
export const commands = null
export const locators = null
export const utils = null
const pool = globalThis.__vitest_worker__?.ctx?.pool
throw new Error(
// eslint-disable-next-line prefer-template
'vitest/browser can be imported only inside the Browser Mode. '
+ (pool
? `Your test is running in ${pool} pool. Make sure your regular tests are excluded from the "test.include" glob pattern.`
: 'Instead, it was imported outside of Vitest.'),
)
View on GitHub (pinned to d568f8ce37)
Solutions
- Run the importing tests in browser mode: vitest --browser (or set projects with browser.enabled).
- Exclude browser tests from the regular suite: set test.include so browser files are not picked up by the default pool run, or split projects.
- Split shared utils so the @vitest/browser import lives only in browser-only files.
- Confirm the active pool is 'browser' for the failing file.
Example fix
// before: shared util imported by both node and browser tests
// src/shared.ts
import { page } from '@vitest/browser' // explodes under node pool
export const click = () => page.click('#x')
// after: vitest.config.ts splits projects
export default defineConfig({
test: {
projects: [
{ test: { name: 'unit', include: ['test/unit/**/*.test.ts'] } },
{ test: { name: 'browser', include: ['test/browser/**/*.test.ts'], browser: { enabled: true, provider: 'playwright' } } },
],
},
}) Defensive patterns
Strategy: validation
Validate before calling
const pool = globalThis.__vitest_worker__?.ctx?.pool
if (pool !== 'browser') {
throw new Error(`vitest/browser requires the browser pool; active pool: ${pool}`)
}
// then import vitest/browser dynamically inside the test Type guard
function inBrowserPool(): boolean {
return globalThis.__vitest_worker__?.ctx?.pool === 'browser'
} Prevention
- Split projects so browser-only files run under the browser pool.
- Keep shared utils that import @vitest/browser out of node-pool test files.
- Run browser tests with vitest --browser or browser.enabled projects.
- Confirm the active pool is 'browser' before importing vitest/browser.
When it happens
Trigger: Importing page, userEvent, server, cdp, etc. from 'vitest/browser' (directly or transitively via a shared util) in a test that runs under the forks/threads/vmThreads/vmForks pool instead of the browser pool. The message names the offending pool when one is set.
Common situations: A shared helper that imports @vitest/browser is also imported by non-browser unit tests; browser tests not excluded from the default test.include so they run under the regular pool; config that failed to set browser.enabled / browser.provider; CI running the full suite without the browser flag.
Related errors
- You've enabled headless mode for "preview" provider but it d
- Cannot take a screenshot without a test path
- Element not found: ${v.element}
- The ${provider.name} provider does not support tracing.
- stopChunkTrace cannot be called outside of the test file.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/36b2a14fadc0a0d9.json.
Report an issue: GitHub.