{"record":{"id":"71a475c7424d77f5","repo":"avajs/ava","slug":"t-notthrows-must-be-called-with-a-function","errorCode":null,"errorMessage":"`t.notThrows()` must be called with a function","messagePattern":"`t\\.notThrows\\(\\)` must be called with a function","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"lib/assert.js","lineNumber":554,"sourceCode":"\t\t\t\t\tformattedDetails: [formatWithLabel('Function threw synchronously. Use `t.throws()` instead:', actual)],\n\t\t\t\t}));\n\t\t\t}\n\n\t\t\tif (isPromise(retval)) {\n\t\t\t\treturn handlePromise(retval, true);\n\t\t\t}\n\n\t\t\tthrow fail(new AssertionError(message, {\n\t\t\t\tassertion: 't.throwsAsync()',\n\t\t\t\tformattedDetails: [formatWithLabel('Function returned:', retval)],\n\t\t\t}));\n\t\t});\n\n\t\tthis.notThrows = withSkip((fn, message) => {\n\t\t\tassertMessage(message, 't.notThrows()');\n\n\t\t\tif (typeof fn !== 'function') {\n\t\t\t\tthrow fail(new AssertionError('`t.notThrows()` must be called with a function', {\n\t\t\t\t\tassertion: 't.notThrows()',\n\t\t\t\t\timproperUsage: {assertion: 'notThrows'},\n\t\t\t\t\tformattedDetails: [formatWithLabel('Called with:', fn)],\n\t\t\t\t}));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tfn();\n\t\t\t} catch (error) {\n\t\t\t\tthrow fail(new AssertionError(message, {\n\t\t\t\t\tassertion: 't.notThrows()',\n\t\t\t\t\tcause: error,\n\t\t\t\t\tformattedDetails: [formatWithLabel('Function threw:', error)],\n\t\t\t\t}));\n\t\t\t}\n\n\t\t\treturn pass();\n\t\t});","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/avajs/ava/blob/bbfd946322fdeca2b547a691d947fb4e18c0c67f/lib/assert.js#L536-L572","documentation":"t.notThrows(fn) asserts that the supplied function executes without throwing. AVA validates the argument type up front and throws this AssertionError when the first argument is not a function. The improperUsage flag marks it as a test-authoring mistake rather than a failed assertion.","triggerScenarios":"Calling t.notThrows(expression) with the result of the call instead of a function (missing arrow wrapper); passing a promise to t.notThrows instead of t.notThrowsAsync; passing undefined/null because the function variable is undefined.","commonSituations":"Copy-pasting t.notThrows(await fn()) patterns; migrating assertions between throws/notThrows/throwsAsync variants and mixing argument shapes; typos where the function name differs from the defined one.","solutions":["Wrap the code under test in a function: t.notThrows(() => { ... })","If the value is a promise, use t.notThrowsAsync(promise) instead","Check for typos/undefined references in the argument you pass"],"exampleFix":"// before\nt.notThrows(loadConfig());\n// after\nawait t.notThrowsAsync(loadConfig());\n// or for sync code:\nt.notThrows(() => loadConfigSync());","handlingStrategy":"type-guard","validationCode":"if (typeof fn !== 'function') {\n  throw new TypeError('t.notThrows requires a function; did you mean notThrowsAsync for promises?');\n}","typeGuard":"const isCallable = (v) => typeof v === 'function';","tryCatchPattern":"try {\n  t.notThrows(fn);\n} catch (e) {\n  if (/must be called with a function/.test(e.message)) {\n    throw new TypeError('Wrap the code: t.notThrows(() => { ... })');\n  }\n  throw e;\n}","preventionTips":["Always pass an arrow function: t.notThrows(() => work())","Use notThrowsAsync for promises, notThrows for functions","Enable TypeScript/linting to catch non-callable arguments"],"tags":["ava","assertion","usage","type-error"],"backgroundTag":"assertion-invalid-argument","analyzedSha":"bbfd946322fdeca2b547a691d947fb4e18c0c67f","analyzedAt":"2026-09-02T01:24:43.834Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}