vitest-dev/vitest · error · Error
snapshot function didn't throw
Error message
snapshot function didn't throw
What it means
After confirming the subject is a function, `getError` invokes it expecting it to throw so the thrown value can be snapshotted. If the function returns normally without throwing, there is no error to snapshot, so Vitest throws `snapshot function didn't throw`. This is the synchronous counterpart of `getError`; in a promise context the error is received directly instead.
Source
Thrown at packages/vitest/src/integrations/snapshot/chai.ts:46
if (typeof expected !== 'function') {
if (!promise) {
throw new Error(
`expected must be a function, received ${typeof expected}`,
)
}
// when "promised", it receives thrown error
return expected
}
try {
expected()
}
catch (e) {
return e
}
throw new Error('snapshot function didn\'t throw')
}
function getTestNames(test: Test) {
return {
filepath: test.file.filepath,
name: getNames(test).slice(1).join(' > '),
testId: test.id,
}
}
function getAssertionName(assertion: Chai.Assertion): string {
const name = chai.util.flag(assertion, '_name') as string | undefined
if (!name) {
throw new Error('Assertion name is not set. This is a bug in Vitest. Please, open a new issue with reproduction.')
}
return name
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Confirm the function still throws for the given input by running it directly first.
- Update the test to use input that does throw, or switch to a non-throw snapshot matcher if the behavior changed.
- Remove any internal `try/catch` that swallows the error inside the wrapped function.
Example fix
// before
expect(() => validate('ok')).toThrowErrorMatchingSnapshot() // validate no longer throws on 'ok'
// after
expect(() => validate('')).toThrowErrorMatchingSnapshot() // input that actually throws Defensive patterns
Strategy: try-catch
Validate before calling
function capturesError(fn: () => unknown): boolean {
try { fn(); return false } catch { return true }
}
if (!capturesError(() => risky())) throw new Error('function does not throw; nothing to snapshot') Try / catch
try {
risky()
throw new Error('expected risky() to throw before snapshotting')
} catch (e) {
expect(() => { throw e }).toThrowErrorMatchingSnapshot()
} Prevention
- Verify the function throws with input that triggers the error path.
- Avoid swallowing errors with internal try/catch inside the wrapped function.
When it happens
Trigger: `expect(() => { /* returns normally */ }).toThrowErrorMatchingSnapshot()` / `...InlineSnapshot()` where the wrapped function does not actually throw.
Common situations: The function was refactored to no longer throw, the triggering input changed, or an earlier `try/catch` swallowed the error before it could propagate out of the wrapped function.
Related errors
- expected must be a function, received ${typeof expected}
- '${getAssertionName(obj)}' cannot be used without test conte
- You must provide an array or set to ${matcherHint('.toBeOneO
- Received value must be an object when the matcher has proper
- ${matcherHint('.toBeSlowerThan')} expects the expected value
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/b7121db09b2c08f7.json.
Report an issue: GitHub.