avajs/ava · error · AssertionError
message
Error message
message
What it means
Thrown by assertExpectations in lib/assert.js:167 when the assertion observed a thrown value that is not a native Error and the expectations did not include `any: true`. The error message is the assertion's own message (e.g. 'Function threw a non-Error' style from the t.throws wrapper); the actual thrown value is attached as `cause` and shown under a '<prefix> exception that is not an error:' label. This keeps throws assertions strict: strings, numbers, and objects thrown ad hoc are rejected unless explicitly allowed.
Source
Thrown at lib/assert.js:167
default: {
throw new AssertionError(`The second argument to \`${assertion}\` contains unexpected properties`, {
assertion,
formattedDetails: [formatWithLabel('Called with:', expectations)],
});
}
}
}
}
return expectations;
}
// Note: this function *must* throw exceptions, since it can be used
// as part of a pending assertion for promises.
function assertExpectations({actual, expectations, message, prefix, assertion, assertionStack}) {
const allowThrowAnything = Object.hasOwn(expectations, 'any') && expectations.any;
if (!isNativeError(actual) && !allowThrowAnything) {
throw new AssertionError(message, {
assertion,
assertionStack,
cause: actual,
formattedDetails: [formatWithLabel(`${prefix} exception that is not an error:`, actual)],
});
}
if (Object.hasOwn(expectations, 'is') && actual !== expectations.is) {
throw new AssertionError(message, {
assertion,
assertionStack,
cause: actual,
formattedDetails: [
formatWithLabel(`${prefix} unexpected exception:`, actual),
formatWithLabel('Expected to be strictly equal to:', expectations.is),
],
});
}View on GitHub (pinned to bbfd946322)
Solutions
- If accepting non-Error throwables is intended, add `any: true`: `t.throws(fn, {any: true})`.
- Preferably fix the code under test to `throw new Error('boom')` or reject with an Error instance.
- If you expected an Error, check what is actually thrown via the `cause` / formatted details and adjust the code under test.
Example fix
// before
t.throwsAsync(async () => http.get('/x'));
// after
t.throwsAsync(async () => http.get('/x'), { any: true });
// or fix the source: throw new Error('request failed'); Defensive patterns
Strategy: try-catch
Validate before calling
async function rejectsWithError(fn) {
try {
await fn();
} catch (e) {
if (!(e instanceof Error) && !Object.hasOwn(expectations ?? {}, 'any')) {
throw new TypeError('code under test throws a non-Error; use {any: true}');
}
return e;
}
throw new Error('expected a throw/rejection');
} Type guard
function isError(v) {
return v instanceof Error || Object.prototype.toString.call(v) === '[object Error]';
} Try / catch
try {
await t.throwsAsync(fn, {any: true});
} catch (error) {
if (error.name === 'AssertionError' && /not an error/.test(error.message)) {
console.error('Threw non-Error:', error.cause);
}
throw error;
} Prevention
- Always throw/reject with `new Error(...)` (or a subclass) in production code.
- For wrappers around promise APIs, wrap non-Error rejection values in an Error with a `cause`.
- Use `{any: true}` only deliberately, when non-Error throwables are part of the contract.
- Lint rules (e.g. no-throw-literal) prevent throwing raw strings/objects.
When it happens
Trigger: Code under test does `throw 'boom'`, `throw {msg: 'boom'}`, `throw undefined`, or rejects with a non-Error, while calling t.throws(fn) / t.throwsAsync(p) without `{any: true}`.
Common situations: Legacy code that throws raw strings; promise rejections with plain objects (`Promise.reject({reason: ...})`); testing wrappers around APIs that reject with non-Error values (e.g. some fetch wrappers); Node util.isError vs class-hierarchy confusion where a fake error class is used.
Related errors
- The `any` property of the second argument to `${assertion}`
- The second argument to `${assertion}` contains unexpected pr
- `t.like()` selector must not contain circular references
- `t.throws()` must be called with a function
- (validateExpectations error for t.throws())
AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02).
Data as JSON: /api/errors/3fd3d0141b7ea563.
Report an issue: GitHub.