cypress-io/cypress · error · Error
Missing vite dev server port.
Error message
Missing vite dev server port.
What it means
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.
Source
Thrown at npm/vite-dev-server/src/devServer.ts:45
let majorVersion: number | undefined = undefined
if (vite.version) {
majorVersion = semverMajor(vite.version)
debug(`Found vite version v${majorVersion}`)
} else {
debug(`vite version not found`)
}
debug('Creating Vite Server')
const server = await devServer.create(config, vite)
debug('Vite server created')
await server.listen()
const { port } = server.config.server
if (!port) {
throw new Error('Missing vite dev server port.')
}
debug('Successfully launched the vite server on port', port)
// Warm up the support file (always) and every spec (run mode only),
// then waitForRequestsIdle, so Vite's deps optimizer has fully processed
// any node_modules imports they pull in before the browser fetches
// them. Skipping this can race a mid-test optimizer re-bundle and
// surface "Failed to fetch dynamically imported module".
//
// Per-spec warmup is required: preprocessor or auto-import plugins can
// inject node_modules imports during transform that Vite's static deps
// scanner doesn't see, so the optimizer would otherwise first discover
// them when the browser fetches the spec.
//
// In open mode (`isTextTerminal === false`), we skip the per-spec
// warmup. The user picks specs interactively and is unlikely to run
// every spec in the suite, so warming all of them up front would payView on GitHub (pinned to 0d85fdc912)
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.
Example fix
// before
devServer: { bundler: 'vite', viteConfig: { server: { port: 0 } } }
// after
devServer: { bundler: 'vite', viteConfig: { server: { port: 5173, strictPort: true } } } Defensive patterns
Strategy: validation
Validate before calling
// choose a concrete port before starting
const PORT = 5173
devServer: { bundler: 'vite', viteConfig: { server: { port: PORT, strictPort: true } } } Type guard
const hasConcretePort = (cfg: any): boolean => typeof cfg?.server?.port === 'number' && cfg.server.port > 0
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Your component devServer config for vite is missing a requir
- ${err}
- CJS builds of vite ${majorVersionNumber} are not supported
- Could not find "vite" in your project's dependencies. Please
- ESM plugin config value '${name}' must be an array of string
AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12).
Data as JSON: /api/errors/a8f47eee81e09290.
Report an issue: GitHub.