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

  1. Let createServer resolve the config itself: call createServer(inlineConfig) with the raw InlineConfig, not a pre-resolved build config.
  2. If you must pre-resolve, use resolveConfig(inlineConfig, 'serve') for the dev server path.
  3. 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

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


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)