avajs/ava · error · AssertionError
The second argument to `${assertion}` contains unexpected pr
Error message
The second argument to `${assertion}` contains unexpected properties What it means
Thrown by validateExpectations in lib/assert.js:150 when the expectation object passed as the second argument to a throws assertion contains a key that is not one of the allowed properties: instanceOf, is, message, name, code, any. This catches typos like `mesage` or `instenceOf` that would otherwise be silently ignored and make the assertion weaker than intended.
Source
Thrown at lib/assert.js:150
throw new AssertionError(`The \`any\` property of the second argument to \`${assertion}\` must be a boolean`, {
assertion,
formattedDetails: [formatWithLabel('Called with:', expectations)],
});
}
for (const key of Object.keys(expectations)) {
switch (key) {
case 'instanceOf':
case 'is':
case 'message':
case 'name':
case 'code':
case 'any': {
continue;
}
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,View on GitHub (pinned to bbfd946322)
Solutions
- Remove the unexpected key, or fix its spelling to one of: instanceOf, is, message, name, code, any.
- If you intended to assert extra properties on the error, assert them separately after capturing the thrown value (e.g. `const err = t.throws(...)` then check `err.code`).
- Check the library docs / types for the exact expectation object shape for the version you are using.
Example fix
// before
t.throws(fn, { mesage: 'boom' });
// after
t.throws(fn, { message: 'boom' }); Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = new Set(['instanceOf', 'is', 'message', 'name', 'code', 'any']);
function assertKnownKeys(expectations) {
for (const key of Object.keys(expectations ?? {})) {
if (!ALLOWED.has(key)) throw new TypeError(`Unknown expectation key: ${key}`);
}
} Type guard
function isExpectationObject(e) {
const allowed = ['instanceOf', 'is', 'message', 'name', 'code', 'any'];
return e != null && typeof e === 'object' && !Array.isArray(e) &&
Object.keys(e).every(k => allowed.includes(k));
} Try / catch
try {
t.throws(fn, expectations);
} catch (error) {
if (error.name === 'AssertionError' && /unexpected properties/.test(error.message)) {
console.warn('Bad expectation keys:', Object.keys(expectations));
}
throw error;
} Prevention
- Memorize the allowed keys: instanceOf, is, message, name, code, any.
- Don't spread arbitrary objects into the expectations argument.
- Use the typed assertion API (TypeScript definitions) to catch typos at compile time.
- Check `instanceOf` spelling — it is not `instanceof` in the expectations object.
When it happens
Trigger: Calling t.throws(fn, {mesage: 'x'}), t.throws(fn, {type: 'Error'}), t.throwsAsync(p, {code: 'ERR', foo: 1}) — any expectation key outside the allowed set hits the switch's default branch.
Common situations: Typos in expectation keys (most common: `mesage`, `instanceOf` vs `instanceof`); reusing options from other assertion libraries (e.g. Chai's `.throw(Error, /msg/, props)` style); spreading extra runtime data into the expectations object; renaming library APIs across versions.
Related errors
- The `any` property of the second argument to `${assertion}`
- message
- `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/ca614866309fa32a.
Report an issue: GitHub.