avajs/ava · error · AssertionError

`t.notThrows()` must be called with a function

Error message

`t.notThrows()` must be called with a function

What it means

t.notThrows(fn) asserts that the supplied function executes without throwing. AVA validates the argument type up front and throws this AssertionError when the first argument is not a function. The improperUsage flag marks it as a test-authoring mistake rather than a failed assertion.

Source

Thrown at lib/assert.js:554

					formattedDetails: [formatWithLabel('Function threw synchronously. Use `t.throws()` instead:', actual)],
				}));
			}

			if (isPromise(retval)) {
				return handlePromise(retval, true);
			}

			throw fail(new AssertionError(message, {
				assertion: 't.throwsAsync()',
				formattedDetails: [formatWithLabel('Function returned:', retval)],
			}));
		});

		this.notThrows = withSkip((fn, message) => {
			assertMessage(message, 't.notThrows()');

			if (typeof fn !== 'function') {
				throw fail(new AssertionError('`t.notThrows()` must be called with a function', {
					assertion: 't.notThrows()',
					improperUsage: {assertion: 'notThrows'},
					formattedDetails: [formatWithLabel('Called with:', fn)],
				}));
			}

			try {
				fn();
			} catch (error) {
				throw fail(new AssertionError(message, {
					assertion: 't.notThrows()',
					cause: error,
					formattedDetails: [formatWithLabel('Function threw:', error)],
				}));
			}

			return pass();
		});

View on GitHub (pinned to bbfd946322)

Solutions

  1. Wrap the code under test in a function: t.notThrows(() => { ... })
  2. If the value is a promise, use t.notThrowsAsync(promise) instead
  3. Check for typos/undefined references in the argument you pass

Example fix

// before
t.notThrows(loadConfig());
// after
await t.notThrowsAsync(loadConfig());
// or for sync code:
t.notThrows(() => loadConfigSync());
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof fn !== 'function') {
  throw new TypeError('t.notThrows requires a function; did you mean notThrowsAsync for promises?');
}

Type guard

const isCallable = (v) => typeof v === 'function';

Try / catch

try {
  t.notThrows(fn);
} catch (e) {
  if (/must be called with a function/.test(e.message)) {
    throw new TypeError('Wrap the code: t.notThrows(() => { ... })');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling t.notThrows(expression) with the result of the call instead of a function (missing arrow wrapper); passing a promise to t.notThrows instead of t.notThrowsAsync; passing undefined/null because the function variable is undefined.

Common situations: Copy-pasting t.notThrows(await fn()) patterns; migrating assertions between throws/notThrows/throwsAsync variants and mixing argument shapes; typos where the function name differs from the defined one.

Related errors


AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02). Data as JSON: /api/errors/71a475c7424d77f5. Report an issue: GitHub.