avajs/ava · error · AssertionError

`t.like()` selector must be a non-empty object

Error message

`t.like()` selector must be a non-empty object

What it means

t.like(actual, selector) compares actual against a subset selector object. Before comparing, AVA validates the selector with isLikeSelector; if it is not a non-empty plain object, AVA throws an AssertionError with the fixed message '`t.like()` selector must be a non-empty object' and a 'Called with:' detail (lib/assert.js:365).

Source

Thrown at lib/assert.js:365

			assertMessage(message, 't.notDeepEqual()');

			const result = concordance.compare(actual, expected, concordanceOptions);
			if (result.pass) {
				const actualDescriptor = result.actual ?? concordance.describe(actual, concordanceOptions);
				throw fail(new AssertionError(message, {
					assertion: 't.notDeepEqual()',
					formattedDetails: [formatDescriptorWithLabel('Value is deeply equal:', actualDescriptor)],
				}));
			}

			return pass();
		});

		this.like = withSkip((actual, selector, message) => {
			assertMessage(message, 't.like()');

			if (!isLikeSelector(selector)) {
				throw fail(new AssertionError('`t.like()` selector must be a non-empty object', {
					assertion: 't.like()',
					formattedDetails: [formatWithLabel('Called with:', selector)],
				}));
			}

			let comparable;
			try {
				comparable = selectComparable(actual, selector);
			} catch (error) {
				if (error === CIRCULAR_SELECTOR) {
					throw fail(new AssertionError('`t.like()` selector must not contain circular references', {
						assertion: 't.like()',
						formattedDetails: [formatWithLabel('Called with:', selector)],
					}));
				}

				throw error;
			}

View on GitHub (pinned to bbfd946322)

Solutions

  1. Ensure the second argument is a non-empty plain object of expected properties: t.like(user, { name: 'Ada' }).
  2. Check argument order — the selector is the second parameter; if you passed actual twice, correct the call.
  3. If the selector is computed, guard against empty/undefined before calling: only invoke t.like when Object.keys(selector).length > 0.

Example fix

// before
t.like(user, filter); // filter is undefined when no filter is given

// after
if (filter && Object.keys(filter).length > 0) {
  t.like(user, filter);
} else {
  t.pass();
}
Defensive patterns

Strategy: validation

Validate before calling

function isLikeSelector(s) {
  return s !== null && typeof s === 'object' && !Array.isArray(s) && Object.keys(s).length > 0;
}
if (!isLikeSelector(selector)) throw new TypeError('t.like() selector must be a non-empty object');

Type guard

const isLikeSelector = (s) => s !== null && typeof s === 'object' && !Array.isArray(s) && Object.getPrototypeOf(s) === Object.prototype && Object.keys(s).length > 0;

Prevention

When it happens

Trigger: Calling t.like(actual, selector) where selector is undefined, null, a primitive (string/number/boolean), an array, an empty object {}, or a non-plain object (e.g. a class instance used as the selector).

Common situations: Variable holding the expected subset is accidentally undefined (typo, failed lookup), passing an empty object intending 'match anything', passing a deeply nested value extracted with optional chaining that resolved to null, or swapping the argument order so the actual value lands in the selector slot.

Related errors


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