avajs/ava · error · AssertionError
(validateExpectations error for t.throwsAsync())
Error message
(validateExpectations error for t.throwsAsync())
What it means
In t.throwsAsync(), invalid expectations cause validateExpectations('t.throwsAsync()', ...) to throw a descriptive usage error, which is caught and re-thrown through fail() so AVA records it as a failed assertion. Before rethrowing, AVA awaits the thrower (swallowing its rejection) to avoid leaving an unhandled promise rejection. The bracketed message is a placeholder for the underlying validateExpectations text.
Source
Thrown at lib/assert.js:456
if (!threw) {
throw fail(new AssertionError(message, {
assertion: 't.throws()',
formattedDetails: [formatWithLabel('Function returned:', retval)],
}));
}
try {
assertExpectations({
assertion: 't.throws()',
actual,
expectations,
message,
prefix: 'Function threw',
});
pass();
return actual;
} catch (error) {
throw fail(error);
}
});
this.throwsAsync = withSkip(async (...args) => {
let [thrower, expectations, message] = args;
try {
assertMessage(message, 't.throwsAsync()');
} catch (error) {
try {
await thrower;
} catch {}
throw error;
}
if (typeof thrower !== 'function' && !isPromise(thrower)) {
throw fail(new AssertionError('`t.throwsAsync()` must be called with a function or promise', {View on GitHub (pinned to bbfd946322)
Solutions
- Read the underlying validateExpectations message for the precise offending expectation.
- Use a constructor, RegExp, string, or valid object ({instanceOf, message, name, code? per docs}).
- Replace Error instances with {instanceOf: ErrorClass} expectations.
Example fix
// before
await t.throwsAsync(promise, new RangeError('out of range'));
// after
await t.throwsAsync(promise, { instanceOf: RangeError, message: 'out of range' }); Defensive patterns
Strategy: validation
Validate before calling
function isValidExpectation(e) {
return e === undefined || typeof e === 'function' || typeof e === 'string' ||
e instanceof RegExp || (typeof e === 'object' && e !== null && !Array.isArray(e));
}
if (!isValidExpectation(expectations)) throw new TypeError('bad t.throwsAsync expectations'); Type guard
const validThrowsAsyncExpectation = (e) => isValidExpectation(e);
Try / catch
try {
await t.throwsAsync(thrower, expectations);
} catch (err) {
if (/expectation/i.test(err.message)) {
t.fail('Invalid t.throwsAsync() expectations: ' + err.message);
} else { throw err; }
} Prevention
- Use {instanceOf: ErrorClass, message} objects instead of Error instances.
- Verify argument order: thrower, expectations, message.
- Validate dynamically built expectation objects before the assertion.
When it happens
Trigger: await t.throwsAsync(promiseOrFn, expectations, ...) with a malformed expectations argument: wrong type (number, boolean, Error instance), an object with unsupported keys, or too many arguments.
Common situations: Passing an instantiated Error instead of a constructor; copy-pasting expectations between t.throws/t.throwsAsync incorrectly; AVA version changes to accepted expectation shapes.
Related errors
- (validateExpectations error for t.throws())
- `t.like()` selector must not contain circular references
- `t.throws()` must be called with a function
- `t.throwsAsync()` must be called with a function or promise
- {message}
AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02).
Data as JSON: /api/errors/4dc3830f1958dec7.
Report an issue: GitHub.