avajs/ava · error · TypeError

Expected an implementation.

Error message

Expected an implementation.

What it means

AVA's t.try() requires an implementation function as its argument (optionally with a title and args). When t.try() is called without a function (e.g. undefined, null, or only a non-function value), the constructor throws this TypeError because there is nothing to execute for the attempt.

Source

Thrown at lib/test.js:105

		this.timeout.clear = () => {
			test.clearTimeout();
		};

		this.teardown = callback => {
			test.addTeardown(callback);
		};

		this.try = async (...attemptArgs) => {
			if (test.isHook) {
				const error = new Error('`t.try()` can only be used in tests');
				test.saveFirstError(error);
				throw error;
			}

			const {args, implementation, title} = parseTestArgs(attemptArgs);

			if (typeof implementation !== 'function') {
				throw new TypeError('Expected an implementation.');
			}

			let attemptTitle;
			if (!title.isSet || title.isEmpty) {
				attemptTitle = `${test.title} ─ attempt ${test.attemptCount + 1}`;
			} else if (title.isValid) {
				attemptTitle = `${test.title} ─ ${title.value}`;
			} else {
				throw new TypeError('`t.try()` titles must be strings');
			}

			if (!test.registerUniqueTitle(attemptTitle)) {
				throw new Error(`Duplicate test title: ${attemptTitle}`);
			}

			let committed = false;
			let discarded = false;

View on GitHub (pinned to bbfd946322)

Solutions

  1. Pass an actual function to t.try(): t.try(tt => { ... }) or t.try('title', tt => { ... }).
  2. Verify the implementation identifier is defined and imported correctly (check for undefined variables/imports).
  3. If passing arguments, use the signature t.try(title, implementation, ...args) with implementation as the second argument.

Example fix

// before
const attempt = t.try('checks value', someValue);

// after
const attempt = t.try('checks value', (tt, value) => {
  tt.is(value, 42);
}, someValue);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof impl !== 'function') throw new TypeError('t.try() requires an implementation function');
const attempt = t.try('title', impl, ...args);

Type guard

const isFunction = (v) => typeof v === 'function';

Try / catch

try {
  attempt = t.try(...attemptArgs);
} catch (err) {
  if (err instanceof TypeError && err.message === 'Expected an implementation.') {
    throw new Error('Bug in test: t.try() called without a function');
  }
  throw err;
}

Prevention

When it happens

Trigger: t.try() called with no arguments; t.try('title') with a title but no implementation; t.try(cb) where cb is undefined due to a bad import or hoisting issue; passing args-only without a function (e.g. t.try('title', arg1) missing the function).

Common situations: Refactoring renamed the callback so the variable is undefined; copying the t.try(title, impl, ...args) signature but forgetting impl; passing a non-function like a promise or an async result instead of the test function.

Related errors


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