{"record":{"id":"3fd3d0141b7ea563","repo":"avajs/ava","slug":"message","errorCode":null,"errorMessage":"message","messagePattern":"message","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"lib/assert.js","lineNumber":167,"sourceCode":"\t\t\t\tdefault: {\n\t\t\t\t\tthrow new AssertionError(`The second argument to \\`${assertion}\\` contains unexpected properties`, {\n\t\t\t\t\t\tassertion,\n\t\t\t\t\t\tformattedDetails: [formatWithLabel('Called with:', expectations)],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn expectations;\n}\n\n// Note: this function *must* throw exceptions, since it can be used\n// as part of a pending assertion for promises.\nfunction assertExpectations({actual, expectations, message, prefix, assertion, assertionStack}) {\n\tconst allowThrowAnything = Object.hasOwn(expectations, 'any') && expectations.any;\n\tif (!isNativeError(actual) && !allowThrowAnything) {\n\t\tthrow new AssertionError(message, {\n\t\t\tassertion,\n\t\t\tassertionStack,\n\t\t\tcause: actual,\n\t\t\tformattedDetails: [formatWithLabel(`${prefix} exception that is not an error:`, actual)],\n\t\t});\n\t}\n\n\tif (Object.hasOwn(expectations, 'is') && actual !== expectations.is) {\n\t\tthrow new AssertionError(message, {\n\t\t\tassertion,\n\t\t\tassertionStack,\n\t\t\tcause: actual,\n\t\t\tformattedDetails: [\n\t\t\t\tformatWithLabel(`${prefix} unexpected exception:`, actual),\n\t\t\t\tformatWithLabel('Expected to be strictly equal to:', expectations.is),\n\t\t\t],\n\t\t});\n\t}","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/avajs/ava/blob/bbfd946322fdeca2b547a691d947fb4e18c0c67f/lib/assert.js#L149-L185","documentation":"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.","triggerScenarios":"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}`.","commonSituations":"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.","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."],"exampleFix":"// before\nt.throwsAsync(async () => http.get('/x'));\n\n// after\nt.throwsAsync(async () => http.get('/x'), { any: true });\n// or fix the source: throw new Error('request failed');","handlingStrategy":"try-catch","validationCode":"async function rejectsWithError(fn) {\n  try {\n    await fn();\n  } catch (e) {\n    if (!(e instanceof Error) && !Object.hasOwn(expectations ?? {}, 'any')) {\n      throw new TypeError('code under test throws a non-Error; use {any: true}');\n    }\n    return e;\n  }\n  throw new Error('expected a throw/rejection');\n}","typeGuard":"function isError(v) {\n  return v instanceof Error || Object.prototype.toString.call(v) === '[object Error]';\n}","tryCatchPattern":"try {\n  await t.throwsAsync(fn, {any: true});\n} catch (error) {\n  if (error.name === 'AssertionError' && /not an error/.test(error.message)) {\n    console.error('Threw non-Error:', error.cause);\n  }\n  throw error;\n}","preventionTips":["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."],"tags":["assertion","non-error-thrown","promise-rejection","ava"],"backgroundTag":"non-error-thrown","analyzedSha":"bbfd946322fdeca2b547a691d947fb4e18c0c67f","analyzedAt":"2026-09-02T01:24:43.834Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}