avajs/ava · error · AssertionError

message ?? 'Test failed via `t.fail()`'

Error message

message ?? 'Test failed via `t.fail()`'

What it means

This is the t.fail() assertion failure itself. When t.fail(message) is called, AVA throws an AssertionError whose message is the caller-provided message, or the default 'Test failed via `t.fail()`' when no message is given (lib/assert.js:288). t.fail unconditionally fails the test — the throw is the intended behavior, not a bug.

Source

Thrown at lib/assert.js:288

	} = {}) {
		const withSkip = assertionFn => {
			assertionFn.skip = skip;
			return assertionFn;
		};

		const assertMessage = (message, assertion) => {
			const result = checkAssertionMessage(message, assertion);
			if (result !== true) {
				throw fail(result);
			}
		};

		this.pass = withSkip(() => pass());

		this.fail = withSkip(message => {
			assertMessage(message, 't.fail()');

			throw fail(new AssertionError(message ?? 'Test failed via `t.fail()`', {
				assertion: 't.fail()',
			}));
		});

		this.is = withSkip((actual, expected, message) => {
			assertMessage(message, 't.is()');

			if (Object.is(actual, expected)) {
				return pass();
			}

			const result = concordance.compare(actual, expected, concordanceOptions);
			const actualDescriptor = result.actual ?? concordance.describe(actual, concordanceOptions);
			const expectedDescriptor = result.expected ?? concordance.describe(expected, concordanceOptions);

			if (result.pass) {
				throw fail(new AssertionError(message, {
					assertion: 't.is()',

View on GitHub (pinned to bbfd946322)

Solutions

  1. Replace t.fail() with real assertions once the test is implemented.
  2. If the failure is unexpected, find the call site — the AssertionError is deliberately thrown there; the assertion name 't.fail()' appears in the error's assertion property.
  3. Use t.pass() or skip the test (test.todo / test.skip) for intentionally unimplemented tests.

Example fix

// before
test('greets', t => {
  t.fail(); // TODO
});

// after
test('greets', async t => {
  const out = greet();
  t.is(out, 'hello');
});
Defensive patterns

Strategy: try-catch

Try / catch

// t.fail throws by design; guard intentional-failure tests:
try {
  t.fail('should not run');
} catch (e) {
  // expected: e.assertion === 't.fail()'
}

Prevention

When it happens

Trigger: Explicitly calling t.fail() or t.fail('my message') anywhere inside a test or hook body; also reached when custom validation code calls t.fail to mark an unexpected branch.

Common situations: See trigger scenarios.

Related errors


AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02). Data as JSON: /api/errors/0cb180b6b231a444. Report an issue: GitHub.