vitejs/vite · error · Error
Config was resolved for a "build", expected a "serve"…
Error message
Config was resolved for a "build", expected a "serve" command.
What it means
Thrown by the dev server factory when the passed ResolvedConfig has config.command === 'build' instead of 'serve'. A dev server requires a config resolved in serve mode because command affects how plugins, options, and optimizations are applied.
Solutions
- Let createServer resolve the config itself: call createServer(inlineConfig) with the raw InlineConfig, not a pre-resolved build config.
- If you must pre-resolve, use resolveConfig(inlineConfig, 'serve') for the dev server path.
- Do not share one ResolvedConfig between build and serve — resolve twice with the correct command.
Example fix
// before const config = await resolveConfig(cfg, 'build') await createServer(config) // throws // after await createServer(cfg) // let Vite resolve for serve // or: const serveConfig = await resolveConfig(cfg, 'serve') await createServer(serveConfig)
Defensive patterns
Strategy: validation
Validate before calling
if (isResolvedConfig(inlineConfig) && inlineConfig.command !== 'serve') {
throw new Error('Pass an InlineConfig or resolve with serve')
} Prevention
- Let createServer resolve the config itself by passing InlineConfig.
- Always pair resolveConfig(inlineConfig, 'serve') with createServer and 'build' with build().
When it happens
Trigger: Passing a config produced by resolveConfig(inlineConfig, 'build') (or build(...) internals) to createServer(). The check at server/index.ts:508 verifies config.command === 'serve'.
Common situations: Reusing a build config object for a dev server in a unified pipeline. Holding a ResolvedConfig from a build and accidentally feeding it to createServer on restart. Custom scripts that resolve config once and branch on command but pass the wrong object.
Related errors
- There is already a server associated with the config.
- Cannot call server.listen in middleware mode.
- Cannot deep clone non-plain object
- Cannot merge config in form of callback
- Cannot print server URLs before server.listen is called.
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/027b786ffa498f31.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vite/src/node/server/index.ts:509
previousShortcutsState?: ShortcutsState<ViteDevServer>
previousRestartPromise?: Promise<void> | null
previousForceOptimizeOnRestart?: boolean
},
): Promise<ViteDevServer> {
// The dev server is a long-running, interactive process whose outputs
// (network responses, HMR updates) cannot be replayed from a cache.
disableCache()
const config = isResolvedConfig(inlineConfig)
? inlineConfig
: await resolveConfig(inlineConfig, 'serve')
if (usedConfigs.has(config)) {
throw new Error(`There is already a server associated with the config.`)
}
if (config.command !== 'serve') {
throw new Error(
`Config was resolved for a "build", expected a "serve" command.`,
)
}
usedConfigs.add(config)
const initPublicFilesPromise = initPublicFiles(config)
const { root, server: serverConfig } = config
const httpsOptions = await resolveHttpsConfig(config.server.https)
const { middlewareMode } = serverConfig
const resolvedOutDirs = getResolvedOutDirs(
config.root,
config.build.outDir,
config.build.rolldownOptions.output,
)
const emptyOutDir = resolveEmptyOutDir(View on GitHub (pinned to b4d66fee14)