vitest-dev/vitest · error · RangeError
vi.when: `times` option must be greater than 0
Error message
vi.when: `times` option must be greater than 0
What it means
The `times` option on `thenReturn`/`thenResolve`/`thenThrow`/`thenReject` controls how many calls a behavior applies to before being exhausted. `validateOptions` rejects any value `<= 0` with a `RangeError` because zero or negative occurrences are nonsensical and would produce an immediately-dead behavior that can never fire.
Source
Thrown at packages/vitest/src/integrations/mock/when.ts:547
: `exhausted (${action.times} of ${action.times})`
}
return action.remaining === Number.POSITIVE_INFINITY
? 'never called'
: `${action.remaining} remaining (out of ${action.times})`
}
function getSymbol(action: BehaviorAction<unknown>): string {
if (hasBeenConsumed(action)) {
return '✓'
}
return '✗'
}
function validateOptions(options: BehaviorOptions | undefined) {
if (typeof options?.times === 'number' && options.times <= 0) {
throw new RangeError('vi.when: `times` option must be greater than 0')
}
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Pass a positive integer (`times: 1` or more), or omit `times` for an indefinite behavior.
- Use the `*Once` variants (`thenReturnOnce`, etc.) when you want exactly one application.
- Guard dynamic `times` values: only set the option when the value is `>= 1`.
Example fix
// before
vi.when(spy).calledWith(1).thenReturn('a', { times: 0 })
// after
vi.when(spy).calledWith(1).thenReturnOnce('a') Defensive patterns
Strategy: validation
Validate before calling
function resolveTimes(n?: number): number | undefined {
if (typeof n === 'number' && n <= 0) throw new RangeError('times must be > 0')
return n
}
vi.when(spy).calledWith(1).thenReturn('a', { times: resolveTimes(maybeZero) }) Type guard
function isValidTimes(n: unknown): n is number | undefined {
return n == null || (typeof n === 'number' && n > 0)
} Prevention
- Use `*Once` variants for single-use behaviors instead of `{ times: 1 }`.
- Guard dynamically computed `times` to only set the option when `>= 1`.
When it happens
Trigger: Passing `{ times: 0 }` or a negative number (e.g. `{ times: -1 }`) to any `then*` method on a `vi.when` `calledWith` chain.
Common situations: Computing `times` from a variable that can be zero, off-by-one in a loop, or confusing `times` with a different option.
Related errors
- ${utils.inspect(chain)} is not a `vi.when` instance
- vi.when: the argument must be a mock function created with `
- vi.when: no behavior defined when called with [${args.map(ar
- vi.mock() expects a string path, but received a ${typeof pat
- vi.unmock() expects a string path, but received a ${typeof p
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/7479ba237404a83f.json.
Report an issue: GitHub.