{"record":{"id":"958c24de190e1014","repo":"Kareadita/Kavita","slug":"reading-list-name-exists","errorCode":"reading-list-name-exists","errorMessage":"reading-list-name-exists","messagePattern":"reading-list-name-exists","errorType":"exception","errorClass":"KavitaException","httpStatus":400,"severity":"error","filePath":"Kavita.Services/ReadingLists/ReadingListService.cs","lineNumber":59,"sourceCode":"    IDirectoryService directoryService,\n    IEntityNamingService namingService)\n    : IReadingListService\n{\n    /// <summary>\n    /// Creates a new Reading List for a User\n    /// </summary>\n    /// <param name=\"userWithReadingList\"></param>\n    /// <param name=\"title\"></param>\n    /// <returns></returns>\n    /// <exception cref=\"KavitaException\"></exception>\n    public async Task<ReadingList> CreateReadingListForUser(AppUser userWithReadingList, string title)\n    {\n        // When creating, we need to make sure Title is unique\n        var normalizedTitle = title.ToNormalized();\n        var hasExisting = userWithReadingList.ReadingLists.Any(l => l.NormalizedTitle == normalizedTitle);\n        if (hasExisting)\n        {\n            throw new KavitaException(\"reading-list-name-exists\");\n        }\n\n        var readingList = new ReadingListBuilder(title).Build();\n        userWithReadingList.ReadingLists.Add(readingList);\n\n        if (!unitOfWork.HasChanges()) throw new KavitaException(\"generic-reading-list-create\");\n        await unitOfWork.CommitAsync();\n        return readingList;\n    }\n\n    /// <summary>\n    ///\n    /// </summary>\n    /// <param name=\"readingList\"></param>\n    /// <param name=\"dto\"></param>\n    /// <exception cref=\"KavitaException\"></exception>\n    public async Task UpdateReadingList(ReadingList readingList, UpdateReadingListDto dto)\n    {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/ReadingLists/ReadingListService.cs#L41-L77","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nvar list = await readingListService.CreateReadingListForUser(user, title);\n\n// after\nvar normalized = title.ToNormalized();\nif (user.ReadingLists.Any(l => l.NormalizedTitle == normalized))\n    return Conflict($\"A reading list named '{title}' already exists\");\nvar list = await readingListService.CreateReadingListForUser(user, title);","handlingStrategy":"validation","validationCode":"var normalized = title.ToNormalized();\nif (userWithReadingList.ReadingLists.Any(l => l.NormalizedTitle == normalized))\n    return Conflict($\"Reading list '{title}' already exists\");\nvar list = await readingListService.CreateReadingListForUser(userWithReadingList, title);","typeGuard":"static bool IsUniqueTitle(string title, IEnumerable<ReadingList> existing) => !existing.Any(l => l.NormalizedTitle == title.ToNormalized());","tryCatchPattern":null,"preventionTips":["Pre-check normalized title uniqueness before create.","Use ToNormalized on the client to predict collisions.","De-duplicate titles in bulk imports."],"tags":["reading-lists","validation","uniqueness","business-rule"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}