{"record":{"id":"f7f8853b41919e17","repo":"vitest-dev/vitest","slug":"failed-to-fetch-browser-runner-html-from-browser","errorCode":null,"errorMessage":"Failed to fetch browser runner HTML from ${browserUrl}","messagePattern":"Failed to fetch browser runner HTML from (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/ui/vite.config.ts","lineNumber":84,"sourceCode":"    outDir: './dist/client',\n  },\n})\n\nfunction devUiScriptPlugin(): Plugin {\n  const BROWSER_SCRIPT_RE = /<script type=\"module\">([\\s\\S]*?window\\.__vitest_browser_runner__\\s*=\\s*\\{[\\s\\S]*?window\\.VITEST_API_TOKEN\\s*=[\\s\\S]*?)<\\/script>/\n\n  const browserUrl = `http://localhost:${process.env.BROWSER_DEV_PORT || '63315'}/__vitest_test__/`\n\n  return {\n    name: 'dev-ui-script',\n    apply(_config, env) {\n      return env.command === 'serve' && env.mode !== 'test'\n    },\n    async transformIndexHtml() {\n      if (process.env.BROWSER_DEV) {\n        const response = await fetch(browserUrl)\n        if (!response.ok) {\n          throw new Error(`Failed to fetch browser runner HTML from ${browserUrl}`)\n        }\n        const browserHtml = await response.text()\n        const browserScript = browserHtml.match(BROWSER_SCRIPT_RE)?.[1]\n        if (!browserScript) {\n          throw new Error('Failed to extract browser runner state from the response')\n        }\n        return [\n          {\n            tag: 'script',\n            attrs: { type: 'module' },\n            children: browserScript,\n            injectTo: 'head-prepend',\n          },\n        ]\n      }\n\n      const token = resolveApiToken(process.cwd()).token\n      return [","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/ui/vite.config.ts#L66-L102","documentation":"This error is internal to Vitest's own development workflow. The devUiScriptPlugin in packages/ui/vite.config.ts fetches the browser test runner's HTML page when the BROWSER_DEV environment variable is set, so the UI dev server can inject the runner's bootstrap script. If the fetch returns a non-OK HTTP status, this error fires. End users of Vitest never hit this; only contributors running the UI dev server in browser-dev mode do.","triggerScenarios":"Running `pnpm dev` for the UI package with BROWSER_DEV set but no Vitest browser server listening at the configured port (BROWSER_DEV_PORT or default 63315), or the server returning an error status.","commonSituations":"Contributor forgot to start the browser test server before starting the UI dev server; wrong BROWSER_DEV_PORT; firewall/proxy blocking localhost fetch.","solutions":["Start the Vitest browser server first so it is listening on the expected port, then start the UI dev server.","Verify BROWSER_DEV_PORT matches the port the browser runner actually uses.","Unset BROWSER_DEV if you are not doing browser-runner UI integration work."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// internal dev workflow — before starting UI dev server with BROWSER_DEV:\nconst port = process.env.BROWSER_DEV_PORT || '63315'\ntry {\n  const res = await fetch(`http://localhost:${port}/__vitest_test__/`)\n  if (!res.ok) throw new Error('browser runner not ready')\n} catch { console.warn('Start the browser runner first') }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Start the Vitest browser server before the UI dev server when BROWSER_DEV is set.","Document the required dev port in the contributor guide."],"tags":["internal","dev-server","browser","network"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}