{"id":"10c1a3323fb5f481","repo":"vitejs/vite","slug":"cannot-print-server-urls-before-server-is-listenin","errorCode":null,"errorMessage":"Cannot print server URLs before server is listening.","messagePattern":"Cannot print server URLs before server is listening\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/preview.ts","lineNumber":191,"sourceCode":"    server.resolvedUrls = null\n  }\n\n  const server: PreviewServer = {\n    config,\n    middlewares: app,\n    httpServer,\n    async close() {\n      if (!closeServerPromise) {\n        closeServerPromise = closeServer()\n      }\n      return closeServerPromise\n    },\n    resolvedUrls: null,\n    printUrls() {\n      if (server.resolvedUrls) {\n        printServerUrls(server.resolvedUrls, options.host, logger.info)\n      } else {\n        throw new Error('Cannot print server URLs before server is listening.')\n      }\n    },\n    bindCLIShortcuts(options) {\n      bindCLIShortcuts(server as PreviewServer, options)\n    },\n  }\n\n  const closeServerAndExit = async (_: unknown, exitCode?: number) => {\n    try {\n      await server.close()\n    } finally {\n      process.exitCode ??= exitCode ? 128 + exitCode : undefined\n      process.exit()\n    }\n  }\n\n  setupSIGTERMListener(closeServerAndExit)\n","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/preview.ts#L173-L209","documentation":"PreviewServer.printUrls at packages/vite/src/node/preview.ts:191 throws if server.resolvedUrls is null. resolvedUrls is only populated after the HTTP server is listening, so calling printUrls before awaiting the listen step has no URLs to print.","triggerScenarios":"Calling server.printUrls() synchronously after createPreviewServer without first awaiting httpServer.listen(port); calling printUrls inside an error path where listening failed; test harness that constructs the server and immediately prints URLs.","commonSituations":"Custom scripts wrapping preview that forget the listen step; copy-paste from dev-server examples that auto-print on listen but applied to a preview server used manually.","solutions":["Await server.listen(previewPort) (or httpServer.listen) before calling server.printUrls().","Move printUrls() into the listen callback / .then so resolvedUrls is populated.","If you do not need to print URLs, simply omit the call."],"exampleFix":"// before\nconst server = await preview({})\nserver.printUrls()\n\n// after\nconst server = await preview({})\nawait server.httpServer.listen(4173)\nserver.printUrls()","handlingStrategy":"validation","validationCode":"function assertListening(server: { resolvedUrls: unknown }) {\n  if (!server.resolvedUrls) {\n    throw new Error('call httpServer.listen() before printUrls()')\n  }\n}\nassertListening(server)","typeGuard":"function isListening(server: { resolvedUrls: unknown }): boolean {\n  return server.resolvedUrls != null\n}","tryCatchPattern":null,"preventionTips":["Call printUrls only after the listen promise/callback fires.","Treat resolvedUrls as the source of truth for whether the server is bound.","In tests, skip printUrls and assert on httpServer.address() instead."],"tags":["preview","server","lifecycle","printurls"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}