vitest-dev/vitest · error · Error

The `test.workspace` option was removed in Vitest 4…

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

Vitest 4 removed `test.workspace` in favor of `test.projects`. During resolution, the presence of a `workspace` key on the resolved config is treated as a hard error (not a warning) and points the user to the migration guide. The same block deprecates `poolOptions`, signalling the broader v4 pool/project rework.

Solutions

  1. Rename `test.workspace` to `test.projects` with the same array contents.
  2. Follow https://vitest.dev/guide/projects for the canonical `test.projects` examples.
  3. Search the whole config chain (including presets and environment-specific overrides) for any lingering `workspace` key and remove it.

Example fix

// before (v3)
export default defineConfig({ test: { workspace: ['packages/*'] } })

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

Strategy: validation

Validate before calling

import type { InlineConfig } from 'vitest/config'

function migrateWorkspace(cfg: any): InlineConfig['test'] {
  if (cfg?.test?.workspace) {
    return { ...cfg.test, projects: cfg.test.projects ?? cfg.test.workspace, workspace: undefined }
  }
  return cfg.test
}

Type guard

function isV4Config(test: any): boolean {
  return !('workspace' in (test ?? {}))
}

Prevention

When it happens

Trigger: A config file with `test: { workspace: [...] }`, a CLI/programmatic merge that injects `workspace`, or a shared base config from a pre-v4 preset still carrying the key.

Common situations: Upgrading Vitest 3→4; monorepo configs that used `workspace` to list sub-projects; tooling (Nx, Turborepo) that emits the v3 workspace shape.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/6a55383271b29f87. Report an issue: GitHub.

Appendix: source

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

    )

    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 1fa9837ec2)