no-assert-throws-async

July 2, 2026 ยท View on GitHub

๐Ÿ“ Disallow passing an async function to assert.throws()/assert.doesNotThrow().

๐Ÿ’ผ This rule is enabled in the following configs: โœ… recommended, โ˜‘๏ธ unopinionated.

๐Ÿ’ก This rule is manually fixable by editor suggestions.

assert.throws() and assert.doesNotThrow() only catch errors thrown synchronously. An async function never throws synchronously: calling it returns a promise that rejects. So assert.throws(async () => { โ€ฆ }) runs the function, gets back a (rejected) promise, sees no synchronous exception, and fails with a "missing expected exception" error regardless of what the function does. The asynchronous counterparts assert.rejects() and assert.doesNotReject() are the correct choice, and their result must be awaited (see no-unawaited-rejects).

This rule reports assert.throws() / assert.doesNotThrow() calls whose first argument is an async function expression. It offers a suggestion to switch to the async equivalent, adding await when the call is a bare statement inside an async function.

Only inline async function expressions are detected. A non-async function that returns a promise is not flagged, since that cannot be determined statically.

MethodReplacement
throwsrejects
doesNotThrowdoesNotReject

Examples

import test from 'node:test';
import assert from 'node:assert';

test('rejects', async () => {
	// โŒ
	assert.throws(async () => {
		await failingOperation();
	}, /boom/);

	// โœ…
	await assert.rejects(async () => {
		await failingOperation();
	}, /boom/);
});