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
- Make titles unique by interpolating the loop variable or an index: t.try(`works: ${item.id}`, impl).
- Omit the title so AVA appends a unique 'attempt N' suffix automatically.
- 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
- Interpolate loop variables into t.try() titles
- Omit the title to let AVA auto-generate a unique one
- Never hardcode the same title in loops or copy-pasted blocks
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
- Duplicate test title: ${title.value}
- Cannot record snapshot ${index} for ${JSON.stringify(belongs
- Expected an implementation.
- `t.try()` titles must be strings
- The `any` property of the second argument to `${assertion}`
AI-assisted analysis of avajs/ava@bbfd946322 (2026-09-02).
Data as JSON: /api/errors/bed49be9b718e560.
Report an issue: GitHub.