{"record":{"id":"4fa867584ea02bbb","repo":"Kareadita/Kavita","slug":"file-doesnt-exist","errorCode":null,"errorMessage":"file-doesnt-exist","messagePattern":"file-doesnt-exist","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/CacheService.cs","lineNumber":233,"sourceCode":"                    }\n                    readingItemService.Extract(file.FilePath, Path.Join(extractPath, extraPath), MangaFormat.Image, files.Count);\n                }\n                directoryService.Flatten(extractDi.FullName);\n            }\n\n        }\n\n        foreach (var file in files)\n        {\n            if (fileCount > 1)\n            {\n                extraPath = file.Id + string.Empty;\n            }\n\n            if (!directoryService.FileSystem.Path.Exists(file.FilePath))\n            {\n                logger.LogError(\"{File} does not exist on disk\", file.FilePath);\n                throw new KavitaException(await localizationService.TranslateAsync(\"file-doesnt-exist\"));\n            }\n\n            switch (file.Format)\n            {\n                case MangaFormat.Archive:\n                    readingItemService.Extract(file.FilePath, Path.Join(extractPath, extraPath), file.Format);\n                    break;\n                case MangaFormat.Epub:\n                case MangaFormat.Pdf:\n                {\n                    if (extractPdfImages)\n                    {\n                        readingItemService.Extract(file.FilePath, Path.Join(extractPath, extraPath), file.Format);\n                        break;\n                    }\n                    removeNonImages = false;\n\n                    directoryService.ExistOrCreate(extractPath);","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/CacheService.cs#L215-L251","documentation":"Thrown during cache extraction when a file tracked in the database no longer exists on disk. The code iterates over files and checks directoryService.FileSystem.Path.Exists(file.FilePath) before extracting; a missing file aborts the entire extraction with this localized 'file-doesnt-exist' KavitaException. It is UI-facing and not Sentry-reported.","triggerScenarios":"A library file was deleted, moved, or renamed on disk after it was scanned into the database; a network share hosting the library was disconnected or remapped; file permissions changed making the file inaccessible; the database references a stale path from a previous server migration.","commonSituations":"User reorganizes their manga/comic folders without rescanning; a USB drive or NAS mount drops; files were moved by an external tool (Sonarr, Radarr, file dedup utilities); library root path changed after a server move.","solutions":["Run a library scan or 'Scan Library' from the UI to sync the database with the actual disk state","Verify the file path exists on disk at the location stored in the database; if the library root moved, update the library folder path in Settings","Check file system permissions to ensure the Kavita process has read access to the library directory","If the file was intentionally deleted, remove it from the library via a scan so stale references are cleaned up"],"exampleFix":"// Before extracting, validate file existence and report a cleaner error:\n// if (!directoryService.FileSystem.Path.Exists(file.FilePath)) {\n//     logger.LogWarning(\"Skipping missing file {Path}\", file.FilePath);\n//     continue; // skip rather than abort entire extraction\n// }","handlingStrategy":"try-catch","validationCode":"// Check file existence before triggering cache extraction:\n// var files = await unitOfWork.ChapterRepository.GetFilesForChaptersAsync(chapterIds, ct);\n// var missing = files.Where(f => !File.Exists(f.FilePath)).ToList();\n// if (missing.Any()) {\n//     await libraryService.ScanLibrary(libraryId, ct); // sync DB with disk\n//     return BadRequest(\"Some files are missing; running a library scan\");\n// }","typeGuard":null,"tryCatchPattern":"// try {\n//     await cacheService.EnsureCacheExtracted(chapterId, ct);\n// } catch (KavitaException ex) when (ex.Message == \"file-doesnt-exist\") {\n//     logger.LogWarning(\"File missing during cache extraction for chapter {ChapterId}\", chapterId);\n//     await mediaErrorService.ReportMediaIssueAsync(filePath, MediaErrorProducer.BookService, \"File missing from disk\", ex, ct);\n//     return NotFound(\"The requested file no longer exists on disk\");\n// }","preventionTips":["Schedule periodic library scans to keep the database in sync with disk state","Avoid moving or renaming files in the library directory outside of Kavita","Use monitoring/alerting on MediaIssue reports to catch missing files early"],"tags":["cache","filesystem","library","missing-file","disk-sync"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}