{"record":{"id":"1b961b9e2adbc2d0","repo":"Kareadita/Kavita","slug":"delete-library-while-scan","errorCode":"delete-library-while-scan","errorMessage":"delete-library-while-scan","messagePattern":"delete-library-while-scan","errorType":"exception","errorClass":"KavitaException","httpStatus":400,"severity":"warning","filePath":"Kavita.Server/Controllers/LibraryController.cs","lineNumber":564,"sourceCode":"            }\n        }\n\n        return Ok();\n    }\n\n    private async Task<bool> DeleteLibrary(int libraryId, int userId, CancellationToken ct = default)\n    {\n        var series = await unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(libraryId, ct: ct);\n        var seriesIds = series.Select(x => x.Id).ToArray();\n        var chapterIds =\n            await unitOfWork.SeriesRepository.GetChapterIdsForSeriesAsync(seriesIds, ct);\n\n        try\n        {\n            if (TaskScheduler.HasScanTaskRunningForLibrary(libraryId))\n            {\n                logger.LogInformation(\"User is attempting to delete a library while a scan is in progress\");\n                throw new KavitaException(await localizationService.TranslateAsync(userId, \"delete-library-while-scan\"));\n            }\n\n            var library = await unitOfWork.LibraryRepository.GetLibraryForIdAsync(libraryId, ct: ct);\n            if (library == null)\n            {\n                throw new KavitaException(await localizationService.TranslateAsync(userId, \"library-doesnt-exist\"));\n            }\n\n\n            // Due to a bad schema that I can't figure out how to fix, we need to erase all RelatedSeries before we delete the library\n            // Aka SeriesRelation has an invalid foreign key\n            foreach (var s in await unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(library.Id, SeriesIncludes.Related, ct))\n            {\n                s.Relations = new List<SeriesRelation>();\n                unitOfWork.SeriesRepository.Update(s);\n            }\n            await unitOfWork.CommitAsync(ct);\n","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Server/Controllers/LibraryController.cs#L546-L582","documentation":"Thrown by LibraryController.DeleteLibrary when TaskScheduler.HasScanTaskRunningForLibrary reports an active scan task for that library. Message is a localization key 'delete-library-while-scan'; being a KavitaException it surfaces as HTTP 500 unless caught earlier. Logged at Information level as an intentional guard.","triggerScenarios":"DELETE /api/library on a library that currently has a library scan/refresh task running or queued in the TaskScheduler.","commonSituations":"User clicks delete while a background scan is mid-flight; a scheduled scan overlaps an admin delete action; a stuck/long-running scan task blocks deletion indefinitely.","solutions":["Cancel or wait for the in-progress scan task to finish, then retry the delete.","From the UI, stop the scan job for that library before issuing delete.","If a scan task is stuck, investigate/cancel it via the task scheduler rather than forcing the delete."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (TaskScheduler.HasScanTaskRunningForLibrary(libraryId))\n    return BadRequest(\"Library scan in progress; retry after it completes\");","typeGuard":null,"tryCatchPattern":"try { await DeleteLibrary(id, userId, ct); }\ncatch (KavitaException ex) { return BadRequest(ex.Message); }","preventionTips":["Check HasScanTaskRunningForLibrary before issuing delete.","From the UI, stop the scan before delete.","Surface scan progress so users know when deletion is safe."],"tags":["library","tasks","state","validation","scan"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}