{"record":{"id":"4dc3830f1958dec7","repo":"avajs/ava","slug":"validateexpectations-error-for-t-throwsasync","errorCode":null,"errorMessage":"(validateExpectations error for t.throwsAsync())","messagePattern":"\\(validateExpectations error for t\\.throwsAsync\\(\\)\\)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"lib/assert.js","lineNumber":456,"sourceCode":"\t\t\tif (!threw) {\n\t\t\t\tthrow fail(new AssertionError(message, {\n\t\t\t\t\tassertion: 't.throws()',\n\t\t\t\t\tformattedDetails: [formatWithLabel('Function returned:', retval)],\n\t\t\t\t}));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tassertExpectations({\n\t\t\t\t\tassertion: 't.throws()',\n\t\t\t\t\tactual,\n\t\t\t\t\texpectations,\n\t\t\t\t\tmessage,\n\t\t\t\t\tprefix: 'Function threw',\n\t\t\t\t});\n\t\t\t\tpass();\n\t\t\t\treturn actual;\n\t\t\t} catch (error) {\n\t\t\t\tthrow fail(error);\n\t\t\t}\n\t\t});\n\n\t\tthis.throwsAsync = withSkip(async (...args) => {\n\t\t\tlet [thrower, expectations, message] = args;\n\n\t\t\ttry {\n\t\t\t\tassertMessage(message, 't.throwsAsync()');\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait thrower;\n\t\t\t\t} catch {}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (typeof thrower !== 'function' && !isPromise(thrower)) {\n\t\t\t\tthrow fail(new AssertionError('`t.throwsAsync()` must be called with a function or promise', {","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/avajs/ava/blob/bbfd946322fdeca2b547a691d947fb4e18c0c67f/lib/assert.js#L438-L474","documentation":"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.","triggerScenarios":"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.","commonSituations":"Passing an instantiated Error instead of a constructor; copy-pasting expectations between t.throws/t.throwsAsync incorrectly; AVA version changes to accepted expectation shapes.","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."],"exampleFix":"// before\nawait t.throwsAsync(promise, new RangeError('out of range'));\n// after\nawait t.throwsAsync(promise, { instanceOf: RangeError, message: 'out of range' });","handlingStrategy":"validation","validationCode":"function isValidExpectation(e) {\n  return e === undefined || typeof e === 'function' || typeof e === 'string' ||\n    e instanceof RegExp || (typeof e === 'object' && e !== null && !Array.isArray(e));\n}\nif (!isValidExpectation(expectations)) throw new TypeError('bad t.throwsAsync expectations');","typeGuard":"const validThrowsAsyncExpectation = (e) => isValidExpectation(e);","tryCatchPattern":"try {\n  await t.throwsAsync(thrower, expectations);\n} catch (err) {\n  if (/expectation/i.test(err.message)) {\n    t.fail('Invalid t.throwsAsync() expectations: ' + err.message);\n  } else { throw err; }\n}","preventionTips":["Use {instanceOf: ErrorClass, message} objects instead of Error instances.","Verify argument order: thrower, expectations, message.","Validate dynamically built expectation objects before the assertion."],"tags":["assertion","ava","invalid-argument","usage-error","async"],"backgroundTag":"invalid-assertion-expectations","analyzedSha":"bbfd946322fdeca2b547a691d947fb4e18c0c67f","analyzedAt":"2026-09-02T01:24:43.834Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}