{"id":"7e3aa7aa474873a1","repo":"vitest-dev/vitest","slug":"can-t-find-browser-origin-url-for-project-this","errorCode":null,"errorMessage":"Can't find browser origin URL for project \"${this.name}\"","messagePattern":"Can't find browser origin URL for project \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/project.ts","lineNumber":475,"sourceCode":"\n  /** @internal */\n  public _getViteEnvironments(): DevEnvironment[] {\n    return Object.values(this.vite.environments || {})\n  }\n\n  /** @internal */\n  public async _openBrowserPage(sessionId: string, pool: {\n    reject: (error: Error) => void\n    parallel?: boolean\n  }): Promise<void> {\n    if (!this.browser) {\n      throw new Error(`browser is not initialized`)\n    }\n\n    const resolvedUrls = this.browser.vite.resolvedUrls\n    const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0]\n    if (!origin) {\n      throw new Error(\n        `Can't find browser origin URL for project \"${this.name}\"`,\n      )\n    }\n\n    const url = new URL('/__vitest_test__/', origin)\n    url.searchParams.set('sessionId', sessionId)\n    const otelCarrier = this.vitest._traces.getContextCarrier()\n    this.vitest._browserSessions.sessionIds.add(sessionId)\n    const sessionPromise = this.vitest._browserSessions.createSession(\n      sessionId,\n      this,\n      pool,\n      { otelCarrier },\n    )\n    const pagePromise = this.browser.provider.openPage(\n      sessionId,\n      url.toString(),\n      { parallel: pool.parallel ?? false },","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/project.ts#L457-L493","documentation":"After confirming the browser exists, _openBrowserPage (project.ts:472-477) reads browser.vite.resolvedUrls to get the local or network origin. If both local[] and network[] are empty/undefined the test page URL cannot be constructed, so Vitest throws. This means the underlying Vite dev server never resolved its listening URLs.","triggerScenarios":"The Vite dev server failed to bind a port (port in use, permission denied), the server was closed before the browser page opened, or server.resolvedUrls was reset. Also possible when a custom middleware/plugin clears resolvedUrls.","commonSituations":"Port 5173 (or configured port) already in use by another process; running in a CI sandbox that blocks the listen syscall; race condition closing the server between init and the first browser test; running headless without network permissions.","solutions":["Check the earlier server-start logs for an EADDRINUSE or listen error and free/switch the port (server.port or browser config).","Ensure the Vite server is not closed/recreated between provider init and the first browser test.","If using a custom server factory, verify it populates resolvedUrls.local.","Run vitest with --no-watch and a single worker to rule out a restart race."],"exampleFix":"// before\nexport default defineConfig({\n  test: { browser: { enabled: true, provider: 'playwright', instances: [{ browser: 'chromium' }] } },\n  server: { port: 5173 }, // collides\n})\n\n// after\nexport default defineConfig({\n  test: { browser: { enabled: true, provider: 'playwright', instances: [{ browser: 'chromium' }] } },\n  server: { port: 0 }, // let vitest pick a free port\n})","handlingStrategy":"validation","validationCode":"const urls = project.browser?.vite?.resolvedUrls\nconst origin = urls?.local?.[0] ?? urls?.network?.[0]\nif (!origin) throw new Error('Vite server has no resolved URL; check port availability')","typeGuard":"function hasOrigin(urls: { local?: string[]; network?: string[] } | undefined): urls is { local: string[] } | { network: string[] } {\n  return !!(urls?.local?.length || urls?.network?.length)\n}","tryCatchPattern":null,"preventionTips":["Use server.port: 0 to avoid port conflicts.","Don't close/recreate the Vite server between init and browser tests.","Ensure the environment allows binding a port (CI sandboxing, permissions)."],"tags":["browser","vite-server","network","port","url"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}