{"id":"8841d86b5e6b51e6","repo":"vitejs/vite","slug":"cannot-call-server-listen-in-middleware-mode","errorCode":null,"errorMessage":"Cannot call server.listen in middleware mode.","messagePattern":"Cannot call server\\.listen in middleware mode\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/server/index.ts","lineNumber":1106,"sourceCode":"        return\n      }\n      return listen(port, ...args)\n    }) as any\n  } else {\n    await initServer(false)\n  }\n\n  return server\n}\n\nasync function startServer(\n  server: ViteDevServer,\n  hostname: Hostname,\n  inlinePort?: number,\n): Promise<void> {\n  const httpServer = server.httpServer\n  if (!httpServer) {\n    throw new Error('Cannot call server.listen in middleware mode.')\n  }\n\n  const options = server.config.server\n  const configPort = inlinePort ?? options.port\n  // When using non strict port for the dev server, the running port can be different from the config one.\n  // When restarting, the original port may be available but to avoid a switch of URL for the running\n  // browser tabs, we enforce the previously used port, expect if the config port changed.\n  const port =\n    (!configPort || configPort === server._configServerPort\n      ? server._currentServerPort\n      : configPort) ?? DEFAULT_DEV_PORT\n  server._configServerPort = configPort\n\n  const serverPort = await httpServerStart(httpServer, {\n    port,\n    strictPort: options.strictPort,\n    host: hostname.host,\n    logger: server.config.logger,","sourceCodeStart":1088,"sourceCodeEnd":1124,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/server/index.ts#L1088-L1124","documentation":"Vite's dev server exposes a server.listen() method that binds the underlying HTTP server to a port. When createServer is called with server.middlewareMode set to true, Vite intentionally does not create an httpServer (it is null), so there is nothing to listen on. Calling server.listen() in that state throws because the connect-based middleware stack is meant to be mounted inside another HTTP server, not bound directly.","triggerScenarios":"Calling server.listen() (or server.listen(port)) on a ViteDevServer instance created with config.server.middlewareMode === true. Also triggered by code paths that assume a standalone server exists, such as calling printUrls or restart on a middleware-mode server that internally invokes listen().","commonSituations":"Embedding Vite as middleware inside an existing Express/Koa/Fastify/Connect app via createServer({ server: { middlewareMode: true } }) and then forgetting the server is not standalone. Copy-pasting startup code from a non-middleware setup into a middleware-mode project. Plugins or framework integrations (e.g. Nuxt, SvelteKit) that call listen() unconditionally without checking middlewareMode.","solutions":["Remove the server.listen() call — in middleware mode you mount server.middlewares into your own HTTP app instead.","Guard the call: only invoke server.listen() when server.config.server.middlewareMode is falsy.","If you need a standalone listening server, remove middlewareMode: true from your config so Vite creates its own httpServer."],"exampleFix":"// before\nconst server = await createServer({ server: { middlewareMode: true } })\nawait server.listen(3000)\n\n// after (middleware mode: mount into your own app)\nconst server = await createServer({ server: { middlewareMode: true } })\napp.use(server.middlewares)\napp.listen(3000)","handlingStrategy":"validation","validationCode":"// Before calling listen, check the server mode\nconst isMiddleware = server.config.server.middlewareMode\nif (!isMiddleware) {\n  await server.listen(port)\n} else {\n  // mount server.middlewares into your own HTTP app instead\n  yourApp.use(server.middlewares)\n}","typeGuard":"// Narrow a ViteDevServer to a listenable one\nimport type { ViteDevServer } from 'vite'\n\nfunction isStandaloneServer(server: ViteDevServer): boolean {\n  return !server.config.server.middlewareMode && server.httpServer != null\n}\n\nif (isStandaloneServer(server)) {\n  await server.listen()\n}","tryCatchPattern":"try {\n  await server.listen(port)\n} catch (e) {\n  if (e instanceof Error && /middleware mode/i.test(e.message)) {\n    // mount into your own app instead\n    app.use(server.middlewares)\n  } else {\n    throw e\n  }\n}","preventionTips":["Centralize server startup in one place that branches on middlewareMode.","Never assume server.httpServer is non-null — check it before listen/printUrls.","Document in your framework layer whether it consumes Vite in middleware or standalone mode."],"tags":["server","middleware-mode","dev-server"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}