{"id":"027b786ffa498f31","repo":"vitejs/vite","slug":"config-was-resolved-for-a-build-expected-a-ser","errorCode":null,"errorMessage":"Config was resolved for a \"build\", expected a \"serve\" command.","messagePattern":"Config was resolved for a \"build\", expected a \"serve\" command\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/server/index.ts","lineNumber":509,"sourceCode":"    previousShortcutsState?: ShortcutsState<ViteDevServer>\n    previousRestartPromise?: Promise<void> | null\n    previousForceOptimizeOnRestart?: boolean\n  },\n): Promise<ViteDevServer> {\n  // The dev server is a long-running, interactive process whose outputs\n  // (network responses, HMR updates) cannot be replayed from a cache.\n  disableCache()\n\n  const config = isResolvedConfig(inlineConfig)\n    ? inlineConfig\n    : await resolveConfig(inlineConfig, 'serve')\n\n  if (usedConfigs.has(config)) {\n    throw new Error(`There is already a server associated with the config.`)\n  }\n\n  if (config.command !== 'serve') {\n    throw new Error(\n      `Config was resolved for a \"build\", expected a \"serve\" command.`,\n    )\n  }\n\n  usedConfigs.add(config)\n\n  const initPublicFilesPromise = initPublicFiles(config)\n\n  const { root, server: serverConfig } = config\n  const httpsOptions = await resolveHttpsConfig(config.server.https)\n  const { middlewareMode } = serverConfig\n\n  const resolvedOutDirs = getResolvedOutDirs(\n    config.root,\n    config.build.outDir,\n    config.build.rolldownOptions.output,\n  )\n  const emptyOutDir = resolveEmptyOutDir(","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/server/index.ts#L491-L527","documentation":"createServer at packages/vite/src/node/server/index.ts:509 asserts config.command === 'serve'. ResolvedConfig objects are bound to the command they were resolved for (build vs serve differ in plugin application, options, and defaults), so handing a build-resolved config to createServer would silently misbehave, hence the explicit throw.","triggerScenarios":"Calling resolveConfig(inlineConfig, 'build') and passing that config to createServer; reusing a config resolved for `vite build` inside a dev script; library code that resolves config once and branches later.","commonSituations":"Building then previewing/dev-ing with the same resolved config; shared config utility that always resolves with 'build'; scripts that resolve config for inspection and then feed it to createServer.","solutions":["Let createServer resolve the config itself: pass an InlineConfig, not a ResolvedConfig.","If you resolve manually, call resolveConfig(inlineConfig, 'serve') for the dev server.","Re-resolve before each command instead of caching one ResolvedConfig across build and serve."],"exampleFix":"// before\nconst config = await resolveConfig({}, 'build')\nconst server = await createServer(config)\n\n// after\nconst server = await createServer({})  // resolves with 'serve'\n// or:\nconst config = await resolveConfig({}, 'serve')\nconst server = await createServer(config)","handlingStrategy":"validation","validationCode":"function assertServeCommand(config: { command?: string }) {\n  if (config.command !== 'serve') {\n    throw new Error('createServer requires a config resolved with command \"serve\"')\n  }\n}","typeGuard":"function isServeConfig(config: { command?: string }): boolean {\n  return config.command === 'serve'\n}","tryCatchPattern":null,"preventionTips":["Pass InlineConfig to createServer so it resolves with command='serve'.","Call resolveConfig(..., 'serve') explicitly if you resolve manually.","Re-resolve config per command rather than sharing one across build and serve."],"tags":["dev-server","config","command","validation"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}