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
- Rename `test.workspace` to `test.projects` with the same array contents.
- Follow https://vitest.dev/guide/projects for the canonical `test.projects` examples.
- 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
- Run the v4 migration codemod/grep for `workspace` before bumping the major.
- Audit shared config presets after upgrading — they often lag the user project.
- Treat the v4 changelog as a checklist of removed keys.
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
- --cache.dir is deprecated
- Environment " " is not a valid environment. Path " " should…
- Found a circular "projects" definition
- Looks like you set "test.environment" to "browser". To…
- No projects matched the filter
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)