vitest-dev/vitest · error · Error

The `test.workspace` option was removed in Vitest 4. Please,

Error message

The `test.workspace` option was removed in Vitest 4. Please, migrate to `test.projects` instead. See https://vitest.dev/guide/projects for examples.

What it means

A hard breaking-change error thrown during config resolution when the resolved config still contains a `workspace` key. Vitest 4 removed `test.workspace` in favor of `test.projects` (which supports the same array-of-project-config shape plus globs). The check `'workspace' in resolved` fires unconditionally, so any presence of the old key aborts startup.

Source

Thrown at packages/vitest/src/node/config/resolveConfig.ts:249

    )

    resolved.retry = {
      ...resolved.retry,
      condition: undefined,
    }
  }

  if (options.pool && typeof options.pool !== 'string') {
    resolved.pool = options.pool.name
    resolved.poolRunner = options.pool
  }

  if ('poolOptions' in resolved) {
    logger.deprecate('`test.poolOptions` was removed in Vitest 4. All previous `poolOptions` are now top-level options. Please, refer to the migration guide: https://v4.vitest.dev/guide/migration#pool-rework')
  }

  if ('workspace' in resolved) {
    throw new Error('The `test.workspace` option was removed in Vitest 4. Please, migrate to `test.projects` instead. See https://vitest.dev/guide/projects for examples.')
  }

  resolved.pool ??= 'forks'

  resolved.project = toArray(resolved.project)
  resolved.provide ??= {}

  // shallow copy tags array to avoid mutating user config
  resolved.tags = [...resolved.tags || []]
  const definedTags = new Set<string>()
  resolved.tags.forEach((tag) => {
    if (!tag.name || typeof tag.name !== 'string') {
      throw new Error(`Each tag defined in "test.tags" must have a "name" property, received: ${JSON.stringify(tag)}`)
    }
    if (definedTags.has(tag.name)) {
      throw new Error(`Tag name "${tag.name}" is already defined in "test.tags". Tag names must be unique.`)
    }
    if (/\s/.test(tag.name)) {

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Rename `test.workspace` to `test.projects` in your vitest.config / workspace file.
  2. Follow the migration guide at https://vitest.dev/guide/projects for the projects shape (globs are now supported).
  3. Search the repo (and any imported config presets) for `workspace:` and update all occurrences.

Example fix

// before
export default defineConfig({ test: { workspace: ['packages/*'] } })
// after
export default defineConfig({ test: { projects: ['packages/*'] } })
Defensive patterns

Strategy: validation

Validate before calling

if ('workspace' in config.test) {
  throw new Error('test.workspace was removed in Vitest 4; use test.projects')
}

Prevention

When it happens

Trigger: Upgrading to Vitest 4 while keeping `test: { workspace: [...] }` in vitest.config (or a workspace file). deepMerge carries the `workspace` key into resolved, and the guard throws with a migration link.

Common situations: Major-version upgrade from Vitest 2/3 to 4 without migrating config; shared config presets not yet updated; docs/tutorials still referencing the old `workspace` option.


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/6a55383271b29f87.json. Report an issue: GitHub.