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
- Wrap the code under test in a function: t.notThrows(() => { ... })
- If the value is a promise, use t.notThrowsAsync(promise) instead
- 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
- Always pass an arrow function: t.notThrows(() => work())
- Use notThrowsAsync for promises, notThrows for functions
- Enable TypeScript/linting to catch non-callable arguments
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
- `t.throws()` must be called with a function
- `t.throwsAsync()` must be called with a function or promise
- `t.notThrowsAsync()` must be called with a function or promi
- `t.snapshot()` can only be used in tests
- `t.regex()` must be called with a string
AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02).
Data as JSON: /api/errors/71a475c7424d77f5.
Report an issue: GitHub.