{"record":{"id":"1ccc454e1fdf81ee","repo":"avajs/ava","slug":"the-assertion-message-must-be-a-string","errorCode":null,"errorMessage":"The assertion message must be a string","messagePattern":"The assertion message must be a string","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"lib/assert.js","lineNumber":279,"sourceCode":"\tconstructor({\n\t\tpass = notImplemented,\n\t\tpending = notImplemented,\n\t\tfail = notImplemented,\n\t\tfailPending = notImplemented,\n\t\tskip = notImplemented,\n\t\tcompareWithSnapshot = notImplemented,\n\t\texperiments = {},\n\t\tdisableSnapshots = false,\n\t} = {}) {\n\t\tconst withSkip = assertionFn => {\n\t\t\tassertionFn.skip = skip;\n\t\t\treturn assertionFn;\n\t\t};\n\n\t\tconst assertMessage = (message, assertion) => {\n\t\t\tconst result = checkAssertionMessage(message, assertion);\n\t\t\tif (result !== true) {\n\t\t\t\tthrow fail(result);\n\t\t\t}\n\t\t};\n\n\t\tthis.pass = withSkip(() => pass());\n\n\t\tthis.fail = withSkip(message => {\n\t\t\tassertMessage(message, 't.fail()');\n\n\t\t\tthrow fail(new AssertionError(message ?? 'Test failed via `t.fail()`', {\n\t\t\t\tassertion: 't.fail()',\n\t\t\t}));\n\t\t});\n\n\t\tthis.is = withSkip((actual, expected, message) => {\n\t\t\tassertMessage(message, 't.is()');\n\n\t\t\tif (Object.is(actual, expected)) {\n\t\t\t\treturn pass();","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/avajs/ava/blob/bbfd946322fdeca2b547a691d947fb4e18c0c67f/lib/assert.js#L261-L297","documentation":"AVA assertion messages must be a string or undefined. assertMessage (lib/assert.js:279) runs checkAssertionMessage on the message passed to any assertion and throws a generic Error (produced by fail(result)) when the message is neither undefined nor a string. This guards assertion output formatting: AVA cannot render non-string messages.","triggerScenarios":"Calling any t.* assertion (t.fail(), t.is(), t.deepEqual(), t.true(), t.log-like assertions, etc.) with a message argument that is a number, boolean, object, Error, null, or other non-string, non-undefined value — e.g. t.is(got, want, 42) or t.fail(someError).","commonSituations":"Passing an Error object as the message out of habit from other frameworks, interpolating to a number, passing null explicitly (null is not undefined), or refactoring where a variable that is sometimes an object is used as the message.","solutions":["Convert the value to a string before passing it: t.is(actual, expected, String(message)) or template literal `${message}`.","Pass the Error's message property instead of the Error itself: t.fail(err.message).","Omit the argument entirely (or pass undefined) if no message is needed; null must be removed since only undefined/string are accepted."],"exampleFix":"// before\nt.fail(new Error('boom'));\n\n// after\nt.fail('boom'); // or t.fail(error.message)","handlingStrategy":"type-guard","validationCode":"function isAssertionMessage(m) { return m === undefined || typeof m === 'string'; }\nif (!isAssertionMessage(message)) throw new TypeError('Assertion message must be a string');","typeGuard":"const isAssertionMessage = (m) => m === undefined || typeof m === 'string';","tryCatchPattern":null,"preventionTips":["Pass string literals or template literals as assertion messages.","Never pass Error objects directly; use err.message.","Use undefined (or omit) rather than null for 'no message'."],"tags":["ava","assertions","type-validation","arguments"],"backgroundTag":"invalid-assertion-message-type","analyzedSha":"bbfd946322fdeca2b547a691d947fb4e18c0c67f","analyzedAt":"2026-09-02T01:24:43.834Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}