{"record":{"id":"a8f47eee81e09290","repo":"cypress-io/cypress","slug":"missing-vite-dev-server-port","errorCode":null,"errorMessage":"Missing vite dev server port.","messagePattern":"Missing vite dev server port\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"npm/vite-dev-server/src/devServer.ts","lineNumber":45,"sourceCode":"  let majorVersion: number | undefined = undefined\n\n  if (vite.version) {\n    majorVersion = semverMajor(vite.version)\n    debug(`Found vite version v${majorVersion}`)\n  } else {\n    debug(`vite version not found`)\n  }\n\n  debug('Creating Vite Server')\n  const server = await devServer.create(config, vite)\n\n  debug('Vite server created')\n\n  await server.listen()\n  const { port } = server.config.server\n\n  if (!port) {\n    throw new Error('Missing vite dev server port.')\n  }\n\n  debug('Successfully launched the vite server on port', port)\n\n  // Warm up the support file (always) and every spec (run mode only),\n  // then waitForRequestsIdle, so Vite's deps optimizer has fully processed\n  // any node_modules imports they pull in before the browser fetches\n  // them. Skipping this can race a mid-test optimizer re-bundle and\n  // surface \"Failed to fetch dynamically imported module\".\n  //\n  // Per-spec warmup is required: preprocessor or auto-import plugins can\n  // inject node_modules imports during transform that Vite's static deps\n  // scanner doesn't see, so the optimizer would otherwise first discover\n  // them when the browser fetches the spec.\n  //\n  // In open mode (`isTextTerminal === false`), we skip the per-spec\n  // warmup. The user picks specs interactively and is unlikely to run\n  // every spec in the suite, so warming all of them up front would pay","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/cypress-io/cypress/blob/0d85fdc91230885bca0a91df278312800a48b727/npm/vite-dev-server/src/devServer.ts#L27-L63","documentation":"Thrown by @cypress/vite-dev-server after `server.listen()` resolves, when `server.config.server.port` is falsy. Vite normally assigns a port (random if 0 was requested); a missing port means the server did not bind or did not report its bound port back into config. Cypress needs a concrete port to point the browser at the dev server, so it refuses to proceed.","triggerScenarios":"Calling devServer.create then server.listen() where the resulting server.config.server.port is undefined/0/null. Occurs when the user's viteConfig sets `server.port: 0` without `strictPort`, when a plugin clears the port, when listen fails silently, or when a Vite version reports the bound port elsewhere than config.server.port.","commonSituations":"A user vite.config that sets `server: { port: 0 }` (request OS-assigned port) but a Vite version that does not backfill the chosen port into config; strictPort conflicts; a misbehaving plugin that mutates server config; running on a restricted environment where listen did not actually bind.","solutions":["In your viteConfig passed to devServer, set an explicit `server.port` (e.g. 5173) instead of 0.","Ensure no Vite plugin in your config overwrites server.port after listen.","Update Vite to a version known to populate config.server.port after listen (Vite 5/6/7 supported per the package's matrix).","If you need an ephemeral port, read the actual bound port from `server.httpServer.address()` in a custom plugin rather than relying on config.server.port."],"exampleFix":"// before\ndevServer: { bundler: 'vite', viteConfig: { server: { port: 0 } } }\n// after\ndevServer: { bundler: 'vite', viteConfig: { server: { port: 5173, strictPort: true } } }","handlingStrategy":"validation","validationCode":"// choose a concrete port before starting\nconst PORT = 5173\ndevServer: { bundler: 'vite', viteConfig: { server: { port: PORT, strictPort: true } } }","typeGuard":"const hasConcretePort = (cfg: any): boolean => typeof cfg?.server?.port === 'number' && cfg.server.port > 0","tryCatchPattern":null,"preventionTips":["Always set an explicit server.port in viteConfig.","Avoid server.port: 0 unless you also backfill the bound port.","Keep Vite within the supported major range for the installed @cypress/vite-dev-server."],"tags":["vite","dev-server","port","network","config"],"backgroundTag":null,"analyzedSha":"0d85fdc91230885bca0a91df278312800a48b727","analyzedAt":"2026-08-12T16:24:28.056Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}