vitest-dev/vitest · error · Error
expect.soft() can only be used inside a test
Error message
expect.soft() can only be used inside a test
What it means
`expect.soft()` records failures on the current test without aborting it, so it needs the active `Test` context (set via the `vitest-test` flag). If no test is in progress, there is nowhere to attach the soft failure and the call throws a plain `Error`.
Solutions
- Move the `expect.soft()` call inside an `it`/`test` body so a test context exists.
- Use plain `expect()` in hooks where soft semantics are not required.
- If asserting in a helper, ensure the helper is only invoked from within a test.
Example fix
// before
beforeAll(() => {
expect.soft(config).toBeDefined()
})
// after
it('has config', () => {
expect.soft(config).toBeDefined()
}) Defensive patterns
Strategy: validation
Validate before calling
// ensure expect.soft is only called where a test context is active
if (!currentTest) { throw new Error('expect.soft requires a test') } Prevention
- Keep expect.soft() inside it()/test() bodies only.
- Use plain expect() in beforeAll/afterAll hooks.
- Ensure shared helpers that assert are invoked from within a test.
When it happens
Trigger: Calling `expect.soft()` at module top level, inside `beforeAll`/`afterAll`, in a setup hook, or in any context where Vitest has not bound the current test to the assertion.
Common situations: Moving an assertion out of a test body into a shared helper called from a hook; using `expect.soft` in a worker or non-test entry point; calling it eagerly during module load.
Related errors
- Cannot annotate tests outside of the test run. The test
- Cannot call "onTestFailed" inside a test hook.
- Cannot call "onTestFinished" inside a test hook.
- expect.poll() must be called inside a test
- Hook () can only be called inside a test
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/91a1e0a9c9f1551b.
Report an issue: GitHub.
Appendix: source
Thrown at packages/expect/src/utils.ts:120
if (name !== 'withTest') {
utils.flag(this, '_name', name)
}
if (!utils.flag(this, 'soft')) {
// avoid WebKit's proper tail call to preserve stacktrace offset for inline snapshot
// https://webkit.org/blog/6240/ecmascript-6-proper-tail-calls-in-webkit
try {
return fn.apply(this, args)
}
finally {
// no lint
}
}
const test: Test = utils.flag(this, 'vitest-test')
if (!test) {
throw new Error('expect.soft() can only be used inside a test')
}
try {
const result = fn.apply(this, args)
if (result && typeof result === 'object' && typeof result.then === 'function') {
return result.then(noop, (err) => {
handleTestError(test, err)
})
}
return result
}
catch (err) {
handleTestError(test, err)
}
}
}View on GitHub (pinned to 1fa9837ec2)