vitest-dev/vitest · error · TypeError
Signature "test(name, fn, { ... })" was deprecated in Vitest
Error message
Signature "test(name, fn, { ... })" was deprecated in Vitest 3 and removed in Vitest 4. Please, provide options as a second argument instead. What it means
In `parseArguments` (suite.ts:266-302), if the third positional argument to `test`/`it`/`suite` is an object (i.e. the old `test(name, fn, { options })` signature), a `TypeError` is thrown. Vitest 3 deprecated and Vitest 4 removed this signature — options must now be the second argument: `test(name, { options }, fn)`.
Source
Thrown at packages/vitest/src/runtime/runner/suite.ts:271
export function createSuiteHooks(): SuiteHooks {
return {
beforeAll: [],
afterAll: [],
beforeEach: [],
afterEach: [],
aroundEach: [],
aroundAll: [],
}
}
const POSITIVE_INFINITY = Number.POSITIVE_INFINITY
function parseArguments<T extends (...args: any[]) => any>(
optionsOrFn: T | object | undefined,
timeoutOrTest: T | number | undefined,
) {
if (timeoutOrTest != null && typeof timeoutOrTest === 'object') {
throw new TypeError(`Signature "test(name, fn, { ... })" was deprecated in Vitest 3 and removed in Vitest 4. Please, provide options as a second argument instead.`)
}
let options: TestOptions = {}
let fn: T | undefined
// it('', () => {}, 1000)
if (typeof timeoutOrTest === 'number') {
options = { timeout: timeoutOrTest }
}
// it('', { retry: 2 }, () => {})
else if (typeof optionsOrFn === 'object') {
options = optionsOrFn
}
if (typeof optionsOrFn === 'function') {
if (typeof timeoutOrTest === 'function') {
throw new TypeError(
'Cannot use two functions as arguments. Please use the second argument for options.',View on GitHub (pinned to d568f8ce37)
Solutions
- Swap the arguments: put options as the second argument and the function third — `test('name', { retry: 2 }, () => {})`.
- Use the codemod/migration guide if upgrading a large suite.
- Optionally use a timeout as third arg (a number is still allowed): `test('name', () => {}, 1000)`.
Example fix
// before (Vitest 3, removed in 4)
test('adds', () => { expect(1+1).toBe(2) }, { retry: 2 })
// after (Vitest 4)
test('adds', { retry: 2 }, () => { expect(1+1).toBe(2) }) Defensive patterns
Strategy: validation
Validate before calling
// Detect the removed signature statically.
function isRemovedSignature(args: unknown[]): boolean {
return typeof args[1] === 'function' && typeof args[2] === 'object' && args[2] !== null && !Array.isArray(args[2])
}
// Lint: ban test(name, fn, {...}) — require options as 2nd arg. Prevention
- When upgrading to Vitest 4, search for `test(.*,.*,\s*{` and swap args.
- Adopt the canonical `test(name, options, fn)` form.
- Run the Vitest migration codemod if available.
When it happens
Trigger: Calling `test('name', () => {}, { retry: 2 })` — function second, options object third; any Vitest 3-or-earlier style three-arg call with an options object in the third slot after upgrading to Vitest 4.
Common situations: Upgrading from Vitest 2/3 to Vitest 4 without migrating test signatures; copying old test patterns from tutorials/docs.
Related errors
- The `browser.provider` configuration was changed to accept a
- Looks like you set "test.environment" to "browser". To enabl
- done() callback is deprecated, use promise instead
- Cannot use two functions as arguments. Please use the second
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/435aa1fcb9777218.json.
Report an issue: GitHub.