Kareadita/Kavita · error · KavitaException
reading-list-name-exists
reading-list-name-exists
Error message
reading-list-name-exists
What it means
Thrown by ReadingListService.CreateReadingListForUser when a reading list with the same NormalizedTitle already exists for the user. Kavita normalizes titles (ToNormalized) so casing/punctuation differences don't create near-duplicate lists; the uniqueness check is on the normalized form, not the raw title.
Source
Thrown at Kavita.Services/ReadingLists/ReadingListService.cs:59
IDirectoryService directoryService,
IEntityNamingService namingService)
: IReadingListService
{
/// <summary>
/// Creates a new Reading List for a User
/// </summary>
/// <param name="userWithReadingList"></param>
/// <param name="title"></param>
/// <returns></returns>
/// <exception cref="KavitaException"></exception>
public async Task<ReadingList> CreateReadingListForUser(AppUser userWithReadingList, string title)
{
// When creating, we need to make sure Title is unique
var normalizedTitle = title.ToNormalized();
var hasExisting = userWithReadingList.ReadingLists.Any(l => l.NormalizedTitle == normalizedTitle);
if (hasExisting)
{
throw new KavitaException("reading-list-name-exists");
}
var readingList = new ReadingListBuilder(title).Build();
userWithReadingList.ReadingLists.Add(readingList);
if (!unitOfWork.HasChanges()) throw new KavitaException("generic-reading-list-create");
await unitOfWork.CommitAsync();
return readingList;
}
/// <summary>
///
/// </summary>
/// <param name="readingList"></param>
/// <param name="dto"></param>
/// <exception cref="KavitaException"></exception>
public async Task UpdateReadingList(ReadingList readingList, UpdateReadingListDto dto)
{View on GitHub (pinned to 9c3e540000)
Solutions
- Check userWithReadingList.ReadingLists for a matching normalized title before calling create, and prompt the user to pick a unique name.
- If importing, de-duplicate titles by normalized form upstream.
- Rename or delete the existing conflicting list first.
- Ensure the client uses the same normalization (Parser.Normalize / ToNormalized) when pre-validating.
Example fix
// before
var list = await readingListService.CreateReadingListForUser(user, title);
// after
var normalized = title.ToNormalized();
if (user.ReadingLists.Any(l => l.NormalizedTitle == normalized))
return Conflict($"A reading list named '{title}' already exists");
var list = await readingListService.CreateReadingListForUser(user, title); Defensive patterns
Strategy: validation
Validate before calling
var normalized = title.ToNormalized();
if (userWithReadingList.ReadingLists.Any(l => l.NormalizedTitle == normalized))
return Conflict($"Reading list '{title}' already exists");
var list = await readingListService.CreateReadingListForUser(userWithReadingList, title); Type guard
static bool IsUniqueTitle(string title, IEnumerable<ReadingList> existing) => !existing.Any(l => l.NormalizedTitle == title.ToNormalized());
Prevention
- Pre-check normalized title uniqueness before create.
- Use ToNormalized on the client to predict collisions.
- De-duplicate titles in bulk imports.
When it happens
Trigger: Calling CreateReadingListForUser with a title whose normalized form collides with an existing entry in userWithReadingList.ReadingLists (e.g. 'My List' vs 'my-list' both normalize to the same key).
Common situations: User creates a list with a name differing only by case/spacing from an existing one; a bulk import of reading lists contains duplicates; or the normalized-title index drifted from raw titles after a normalization change.
Related errors
- name-already-in-use
- cant-delete-default-profile
- cant-assign-devices-to-default
- reading-profiles-device-overlap
- generic-reading-list-create
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/958c24de190e1014.
Report an issue: GitHub.