{"id":"03e2e8ea89093d4e","repo":"vitejs/vite","slug":"the-directory-clientoutdir-does-not-exist-di","errorCode":null,"errorMessage":"The directory \"${clientOutDir}\" does not exist. Did you build your project?","messagePattern":"The directory \"(.+?)\" does not exist\\. Did you build your project\\?","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/preview.ts","lineNumber":153,"sourceCode":"    inlineConfig,\n    'serve',\n    'production',\n    'production',\n    true,\n  )\n\n  const clientOutDir = config.environments.client.build.outDir\n  const distDir = path.resolve(config.root, clientOutDir)\n  if (\n    !fs.existsSync(distDir) &&\n    // error if no plugins implement `configurePreviewServer`\n    config.plugins.every((plugin) => !plugin.configurePreviewServer) &&\n    // error if called in CLI only. programmatic usage could access `httpServer`\n    // and affect file serving\n    process.argv[1]?.endsWith(path.normalize('bin/vite.js')) &&\n    process.argv[2] === 'preview'\n  ) {\n    throw new Error(\n      `The directory \"${clientOutDir}\" does not exist. Did you build your project?`,\n    )\n  }\n\n  const httpsOptions = await resolveHttpsConfig(config.preview.https)\n  const app = connect() as Connect.Server\n  const httpServer = await resolveHttpServer(app, httpsOptions)\n  setClientErrorHandler(httpServer, config.logger)\n\n  const options = config.preview\n  const logger = config.logger\n\n  const closeHttpServer = createServerCloseFn(httpServer)\n\n  // Promise used by `server.close()` to ensure `closeServer()` is only called once\n  let closeServerPromise: Promise<void> | undefined\n  const closeServer = async () => {\n    teardownSIGTERMListener(closeServerAndExit)","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/preview.ts#L135-L171","documentation":"preview() at packages/vite/src/node/preview.ts:153 checks that the client output directory exists before serving it. The throw is guarded by three conditions: the dir is missing, no plugin implements configurePreviewServer, and the process was launched as the `vite preview` CLI command. If any of those is false Vite stays silent (e.g. programmatic callers may serve their own files).","triggerScenarios":"Running `vite preview` (or `npx vite preview`) before `vite build`; build wrote to a different outDir than config.environments.client.build.outDir points at; outDir was deleted between build and preview; a custom config sets a non-default build.outDir that was never populated.","commonSituations":"CI/ deploy script that calls preview without a prior build step; switching build.outDir (e.g. to 'dist/static') in only one place; running preview against a freshly cloned repo with no build artifacts; renaming or cleaning the dist folder manually.","solutions":["Run `vite build` (or your build script) before `vite preview` so the outDir is populated.","Verify config.environments.client.build.outDir / build.outDir matches the directory your build actually writes to.","If previewing custom output, implement a configurePreviewServer plugin so Vite does not enforce the default clientOutDir check.","Invoke preview programmatically (not via the CLI) if you intend to serve files yourself and want to skip the guard."],"exampleFix":"// before: preview runs with nothing built\n//   $ vite preview\n\n// after: build first, then preview\n//   $ vite build && vite preview","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs'\nimport { resolveConfig } from 'vite'\nconst cfg = await resolveConfig({}, 'serve', 'production')\nconst outDir = cfg.environments.client.build.outDir\nif (!existsSync(outDir)) {\n  throw new Error(`Run \\`vite build\\` first; ${outDir} is missing`)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair `vite preview` with a preceding `vite build` in scripts and CI.","Keep build.outDir consistent across build and preview configs.","If serving custom output, implement configurePreviewServer to opt out of the default check."],"tags":["preview","build","cli","outdir"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}