{"record":{"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, except if the config port changed.\n  const port =\n    configPort === server._configServerPort\n      ? (server._currentServerPort ?? configPort)\n      : configPort\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/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/node/server/index.ts#L1088-L1124","documentation":"Thrown by startServer() (invoked from server.listen()) when server.httpServer is absent, which is exactly the case in middleware mode. In middleware mode Vite does not create a Node http.Server, so binding a port is meaningless and is rejected.","triggerScenarios":"Calling server.listen(port) on a server created with server.middlewareMode: true. The check `if (!httpServer)` at server/index.ts:1105 detects that there is no listener to bind.","commonSituations":"Using Vite as middleware inside an existing HTTP server and accidentally also calling server.listen. Copying standalone-server sample code into a middleware-mode integration. Race between custom server bootstrap and Vite listen call.","solutions":["Do not call server.listen() in middleware mode — the parent HTTP server already listens; you only need app.use(vite.middlewares).","If you want Vite to manage listening, remove server.middlewareMode from the config.","Guard the call: if (!vite.config.server.middlewareMode) await vite.listen()."],"exampleFix":"// before\nconst vite = await createServer({ server: { middlewareMode: true } })\nawait vite.listen(5173) // throws\n// after\nconst vite = await createServer({ server: { middlewareMode: true } })\napp.use(vite.middlewares)\napp.listen(5173)","handlingStrategy":"validation","validationCode":"if (!server.config.server.middlewareMode) {\n  await server.listen(port)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve server.listen() for standalone mode only.","In middleware mode, only call app.use(vite.middlewares); let the parent server listen."],"tags":["dev-server","middleware-mode","lifecycle"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}