vitest-dev/vitest · error · AssertionError

expected function to throw an error, but it didn't

Error message

expected function to throw an error, but it didn't

What it means

AssertionError thrown by toThrow/toThrowError when the target function (obj) was invoked and did not throw, in the non-negated form. The matcher invokes obj() inside try/catch (line 782-788); if isThrow stays false and !isNot, it reports that no error was thrown.

Source

Thrown at packages/expect/src/jest-expect.ts:797

      }
      else {
        let isThrow = false
        try {
          obj()
        }
        catch (err) {
          isThrow = true
          thrown = err
        }

        if (!isThrow && !isNot) {
          const message
            = utils.flag(this, 'message')
              || 'expected function to throw an error, but it didn\'t'
          const error = {
            showDiff: false,
          }
          throw new AssertionError(message, error, utils.flag(this, 'ssfi'))
        }
      }

      if (typeof expected === 'function') {
        const name = expected.name || expected.prototype.constructor.name
        return this.assert(
          thrown && thrown instanceof expected,
          `expected error to be instance of ${name}`,
          `expected error not to be instance of ${name}`,
          expected,
          thrown,
        )
      }

      if (isError(expected)) {
        const equal = jestEquals(thrown, expected, [
          ...customTesters,
          iterableEquality,

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Confirm the function actually throws under the test conditions (add a console.log or step through).
  2. If the function returns an error instead of throwing, assert on the return value with toEqual/toMatchObject instead of toThrow.
  3. If the throw is conditional, ensure the input satisfies the throwing branch.

Example fix

// before
expect(() => validate('')).toThrow(ValidationError);
// after (validate returns { error } instead)
expect(validate('')).toEqual({ error: expect.any(ValidationError) });
Defensive patterns

Strategy: validation

Validate before calling

let threw = false;
try { fn(); } catch { threw = true; }
if (!threw) throw new Error('fn did not throw under test conditions');

Prevention

When it happens

Trigger: expect(fn).toThrow() where fn() returns normally without throwing. Equivalent to expect(fn).toThrow(undefined) or .toThrow('msg')/.toThrow(/re/) when no error is raised.

Common situations: The code under test does not actually throw on the given input — e.g. a validation function that returns false instead of throwing, an async function whose rejection was swallowed, or a conditional throw that was not triggered.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/c6d98b9e195d54d3.json. Report an issue: GitHub.