{"record":{"id":"f6a922dd11c1ffb1","repo":"Kareadita/Kavita","slug":"generic-error-f6a922","errorCode":null,"errorMessage":"generic-error","messagePattern":"generic-error","errorType":"exception","errorClass":"KavitaException","httpStatus":500,"severity":"error","filePath":"Kavita.Services/Reading/ReaderService.cs","lineNumber":611,"sourceCode":"        {\n            if (next)\n            {\n                return chapter.Id;\n            }\n\n            var chapterNum = accessor(chapter);\n            if (currentChapterNumber.Equals(chapterNum)) next = true;\n        }\n\n        return -1;\n    }\n\n    public async Task<HourEstimateRangeDto> GetEstimateToCompletionForChapter(int userId, int seriesId, int chapterId)\n    {\n        var series = await unitOfWork.SeriesRepository.GetSeriesDtoByIdAsync(seriesId, userId);\n        var chapter = await unitOfWork.ChapterRepository.GetChapterDtoAsync(chapterId, userId);\n        if (series == null || chapter == null)\n            throw new KavitaException(await localizationService.TranslateAsync(userId, \"generic-error\"));\n\n        if (series.Format == MangaFormat.Epub)\n        {\n            // Get the word counts for all the pages\n            var pageCounts = await bookService.GetWordCountsPerPage(chapter.Files.First().FilePath); // TODO: Cache\n            if (pageCounts == null) return GetTimeEstimate(chapter.WordCount, 0, true);\n\n            // Sum character counts for unread pages\n            var toReadCharacters = pageCounts\n                .Where(kvp => kvp.Key > chapter.PagesRead)\n                .Sum(kvp => kvp.Value);\n\n            var wordsLeft = WordCountAnalyzerService.GetWordCount(toReadCharacters);\n            return GetTimeEstimate(wordsLeft, 0, true);\n        }\n\n        var pagesLeft = chapter.Pages - chapter.PagesRead;\n","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/Reading/ReaderService.cs#L593-L629","documentation":"Thrown by GetEstimateToCompletionForChapter when either the series DTO or chapter DTO lookup returns null. The message is the localized 'generic-error' ('Something went wrong, please try again') resolved per-user via localizationService.TranslateAsync. It is a catch-all guard before computing reading-time estimates.","triggerScenarios":"Estimate endpoint called with a seriesId or chapterId that does not resolve (deleted, no access, stale id), or the chapter does not belong to the series/user.","commonSituations":"UI requests a time-to-complete estimate for a chapter that was just removed by a rescan; a stale chapter id cached in the client; user lacks access to the series' library.","solutions":["Verify seriesId and chapterId are valid and accessible to the user before requesting the estimate.","Refresh the series/chapter data in the client after a library scan.","If the error is unexpected, check logs for which of series/chapter was null and re-import the missing entity."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var series = await unitOfWork.SeriesRepository.GetSeriesDtoByIdAsync(seriesId, userId);\nvar chapter = await unitOfWork.ChapterRepository.GetChapterDtoAsync(chapterId, userId);\nif (series == null || chapter == null) return null; // nothing to estimate\nreturn await readerService.GetEstimateToCompletionForChapter(userId, seriesId, chapterId);","typeGuard":"public static bool ResolvesBoth(SeriesDto? s, ChapterDto? c) => s is not null && c is not null;","tryCatchPattern":"try { return await readerService.GetEstimateToCompletionForChapter(userId, seriesId, chapterId); }\ncatch (KavitaException) { return null; // estimate unavailable, degrade gracefully }","preventionTips":["Verify seriesId and chapterId resolve for the user before requesting estimates.","Treat the estimate as optional UI metadata so a null/error doesn't block reading.","Refresh client chapter data after structural library changes."],"tags":["reading","estimate","generic","not-found"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}