vitest-dev/vitest · critical · Error
Tester HTML file " " doesn't exist.
Error message
Tester HTML file "${testerHtmlPath}" doesn't exist. What it means
The ProjectBrowser constructor resolves the tester HTML file: either the user-supplied config.browser.testerHtmlPath (resolved against config.root) or the built-in client/tester/tester.html under distRoot. If that file is absent on disk, the tester iframe cannot be served, so construction aborts.
Solutions
- If you set browser.testerHtmlPath, verify the file exists with `fs.existsSync(path.resolve(config.root, testerHtmlPath))`.
- If using the default, rebuild the browser package (`pnpm build --filter @vitest/browser`) or reinstall from npm to restore dist/client/tester/tester.html.
- Check that @vitest/browser is not being resolved from a src directory due to a faulty `exports` map or a yarn link.
- Confirm the published package version is intact; downgrade or upgrade if the tarball is known-broken.
Example fix
// before
browser: { testerHtmlPath: './custom-tester.html' } // missing file
// after
browser: { testerHtmlPath: './test/custom-tester.html' } // verified to exist Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs'
import { resolve } from 'node:path'
function testerHtmlExists(root: string, custom?: string, distRoot = ''): boolean {
const p = custom ? resolve(root, custom) : resolve(distRoot, 'client/tester/tester.html')
return existsSync(p)
} Prevention
- Run `pnpm build` for @vitest/browser before running tests against a linked build.
- Verify custom testerHtmlPath values with existsSync at config load.
- Reinstall from npm if the published tarball appears to be missing dist files.
When it happens
Trigger: Setting browser.testerHtmlPath to a path that does not exist; running @vitest/browser from source/CI without having built the client (so distRoot/client/tester/tester.html is missing); a packaging defect where the published tarball omits the tester html.
Common situations: Custom testerHtmlPath with a typo or relative path that resolves outside the project root; running against a linked, un-built @vitest/browser in a monorepo; an npm publish that excluded the dist/client/tester directory.
Related errors
- All browser instances within a project must use the same…
- "browser.instances" was set in the config, but the array is…
- browser is not initialized
- Browser Mode requires the "provider" to always be specified.
- Browser Mode was enabled, but provider was not specified…
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/0e782de344636d3d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/browser/src/node/project.ts:52
public state: BrowserServerState = new BrowserServerState()
constructor(
public parent: ParentBrowserProject,
public project: TestProject,
public base: string,
) {
this.vitest = project.vitest
this.config = project.config
this.vite = parent.vite
// instances can override testerHtmlPath
const testerHtmlPath = project.config.browser.testerHtmlPath
? resolve(project.config.root, project.config.browser.testerHtmlPath)
: resolve(distRoot, 'client/tester/tester.html')
// TODO: when config resolution is rewritten, project and parentProject should be created before the vite server is started
if (!existsSync(testerHtmlPath)) {
throw new Error(`Tester HTML file "${testerHtmlPath}" doesn't exist.`)
}
this.testerFilepath = testerHtmlPath
this.testerHtml = readFile(
this.testerFilepath,
'utf8',
).then(html => (this.testerHtml = html))
}
private commands = {} as Record<string, BrowserCommand<any, any>>
public registerCommand<K extends keyof BrowserCommands>(
name: K,
cb: BrowserCommand<
Parameters<BrowserCommands[K]>,
ReturnType<BrowserCommands[K]>
>,
): void {
if (!/^[a-z_$][\w$]*$/i.test(name)) {View on GitHub (pinned to 1fa9837ec2)