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

  1. Move the `expect.soft()` call inside an `it`/`test` body so a test context exists.
  2. Use plain `expect()` in hooks where soft semantics are not required.
  3. 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

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


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)