avajs/ava · error · AssertionError
`t.notThrowsAsync()` must be called with a function or promi
Error message
`t.notThrowsAsync()` must be called with a function or promise
What it means
t.notThrowsAsync() asserts that a function returning a promise (or a promise itself) does not reject. AVA validates its argument up front and throws this AssertionError when it is neither a function nor a promise-like object. Like other improperUsage errors, it signals a mistake in how the assertion was invoked.
Source
Thrown at lib/assert.js:586
}));
}
return pass();
});
this.notThrowsAsync = withSkip(async (nonThrower, message) => {
try {
assertMessage(message, 't.notThrowsAsync()');
} catch (error) {
try {
await nonThrower;
} catch {}
throw error;
}
if (typeof nonThrower !== 'function' && !isPromise(nonThrower)) {
throw fail(new AssertionError('`t.notThrowsAsync()` must be called with a function or promise', {
assertion: 't.notThrowsAsync()',
formattedDetails: [formatWithLabel('Called with:', nonThrower)],
}));
}
const handlePromise = async (promise, wasReturned) => {
// Create an error object to record the stack before it gets lost in the promise chain.
const assertionStack = getAssertionStack();
// Handle "promise like" objects by casting to a real Promise.
const intermediate = Promise.resolve(promise).then(noop, error => {
throw failPending(new AssertionError(message, {
assertion: 't.notThrowsAsync()',
assertionStack,
formattedDetails: [formatWithLabel(`${wasReturned ? 'Returned promise' : 'Promise'} rejected with:`, error)],
}));
});
pending(intermediate, assertionStack);
View on GitHub (pinned to bbfd946322)
Solutions
- Pass the promise directly: t.notThrowsAsync(asyncFn()) without await
- Or pass a function returning a promise: t.notThrowsAsync(() => asyncFn())
- If the code is synchronous, use t.notThrows(() => syncFn()) instead
Example fix
// before await t.notThrowsAsync(await fetchUser(id)); // after await t.notThrowsAsync(fetchUser(id));
Defensive patterns
Strategy: type-guard
Validate before calling
const arg = asyncFn();
if (typeof arg !== 'function' && !(arg && typeof arg.then === 'function')) {
throw new TypeError('notThrowsAsync needs a function or a promise — remove any await');
} Type guard
const isFunctionOrPromise = (v) => typeof v === 'function' || (v !== null && typeof v === 'object' && typeof v.then === 'function');
Try / catch
try {
await t.notThrowsAsync(promiseOrFn);
} catch (e) {
if (/must be called with a function or promise/.test(e.message)) {
throw new TypeError('Do not await before passing: t.notThrowsAsync(asyncFn())');
}
throw e;
} Prevention
- Never write t.notThrowsAsync(await fn())
- Pass either the promise or a zero-arg function returning a promise
- Use async functions so non-promise returns are impossible
When it happens
Trigger: Passing an awaited value (the resolved result) instead of the promise; passing a plain value, number, or string; passing a function to t.notThrowsAsync that is meant for t.notThrows without returning a promise while also failing the type check because a non-callable was given.
Common situations: Writing t.notThrowsAsync(await asyncFn()) — the await removes the promise; confusing t.notThrows and t.notThrowsAsync during refactors; passing null/undefined due to an earlier failed lookup.
Related errors
- `t.throwsAsync()` must be called with a function or promise
- `t.notThrows()` must be called with a function
- `t.snapshot()` can only be used in tests
- The `any` property of the second argument to `${assertion}`
- The second argument to `${assertion}` contains unexpected pr
AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02).
Data as JSON: /api/errors/6c267f1b7bc9de6f.
Report an issue: GitHub.