avajs/ava · error · Error

Duplicate test title: ${attemptTitle}

Error message

Duplicate test title: ${attemptTitle}

What it means

Each title generated for a t.try() attempt must be unique within the test. AVA registers every attempt title (auto-generated 'attempt N' or user-provided) via registerUniqueTitle; when the title was already registered, this Error is thrown to prevent ambiguous test output and snapshot bookkeeping.

Source

Thrown at lib/test.js:118

			}

			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;

			const {assertCount, deferredSnapshotRecordings, errors, logs, passed, snapshotCount, startingSnapshotCount} = await test.runAttempt(attemptTitle, t => implementation(t, ...args));

			return {
				errors,
				logs: [...logs], // Don't allow modification of logs.
				passed,
				title: attemptTitle,
				commit({retainLogs = true} = {}) {
					if (committed) {
						return;
					}

					if (discarded) {

View on GitHub (pinned to bbfd946322)

Solutions

  1. Make titles unique by interpolating the loop variable or an index: t.try(`works: ${item.id}`, impl).
  2. Omit the title so AVA appends a unique 'attempt N' suffix automatically.
  3. Deduplicate or suffix titles from dynamic data before passing them to t.try().

Example fix

// before
for (const user of users) {
  t.try('validates user', impl);
}

// after
users.forEach((user, i) => {
  t.try(`validates user ${user.id ?? i}`, impl);
});
Defensive patterns

Strategy: validation

Validate before calling

const seen = new Set();
function uniqueTitle(base) {
  let title = base, i = 1;
  while (seen.has(title)) title = `${base} (${i++})`;
  seen.add(title);
  return title;
}
const attempt = t.try(uniqueTitle('validates user'), impl);

Type guard

const isFreshTitle = (title, registered) => !registered.has(title);

Try / catch

try {
  const attempt = t.try(title, impl);
} catch (err) {
  if (/^Duplicate test title: /.test(err.message)) {
    throw new Error(`Fix your test: t.try title "${title}" used twice`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling t.try twice with the same explicit title inside one test; a loop that creates t.try attempts with identical constant titles; an auto-generated title colliding because the attempt count tracking was bypassed.

Common situations: Loops like for (const item of items) { t.try('works', impl) } producing repeated titles; duplicating a t.try line when copy-pasting tests; generating titles from data that contains duplicates.

Related errors


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