{"record":{"id":"b12c7819af37e0b3","repo":"Kareadita/Kavita","slug":"the-directory-doesn-t-exist","errorCode":null,"errorMessage":"The directory doesn't exist","messagePattern":"The directory doesn't exist","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/DirectoryService.cs","lineNumber":797,"sourceCode":"    /// up processing.\n    /// NOTE: This is no longer parallel due to user's machines locking up\n    /// </summary>\n    /// <param name=\"root\">Directory to scan</param>\n    /// <param name=\"action\">Action to apply on file path</param>\n    /// <param name=\"searchPattern\">Regex pattern to search against</param>\n    /// <param name=\"logger\"></param>\n    /// <exception cref=\"ArgumentException\"></exception>\n    public int TraverseTreeParallelForEach(string root, Action<string> action, string searchPattern, ILogger logger)\n    {\n        //Count of files traversed and timer for diagnostic output\n        var fileCount = 0;\n\n\n        // Data structure to hold names of subfolders to be examined for files.\n        var dirs = new Stack<string>();\n\n        if (!FileSystem.Directory.Exists(root)) {\n            throw new ArgumentException(\"The directory doesn't exist\");\n        }\n\n        dirs.Push(root);\n\n        while (dirs.Count > 0) {\n            var currentDir = dirs.Pop();\n            IEnumerable<string> subDirs;\n            string[] files;\n\n            try {\n                subDirs = GetDirectories(currentDir);\n            }\n            // Thrown if we do not have discovery permission on the directory.\n            catch (UnauthorizedAccessException e) {\n                logger.LogCritical(e, \"Unauthorized access on {Directory}\", currentDir);\n                continue;\n            }\n            // Thrown if another process has deleted the directory after we retrieved its name.","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/DirectoryService.cs#L779-L815","documentation":"An ArgumentException thrown by TraverseTreeParallelForEach when the root directory path does not exist. Unlike error [54] which uses DirectoryNotFoundException, this method uses ArgumentException, meaning the parameter value itself is considered invalid. This is used for parallel file enumeration and is the entry-point guard before the traversal stack begins.","triggerScenarios":"Root path passed to the parallel tree traversal is null, empty, or refers to a directory that does not exist; the root was valid when scheduled but was deleted/unmounted before execution began.","commonSituations":"Library scan triggered for a root that was just unmounted; scheduled task references a path from a removed library; path constructed dynamically from configuration that has since changed; container restart with missing volume mounts.","solutions":["Validate the root path exists before calling TraverseTreeParallelForEach","Check that the library root is properly mounted and accessible","If the library was removed, cancel any pending scan tasks that reference its path","Add a pre-flight check in the calling code to skip non-existent roots with a warning log"],"exampleFix":"// Pre-flight check in the caller:\n// if (!FileSystem.Directory.Exists(root)) {\n//     logger.LogWarning(\"Skipping scan; root does not exist: {Root}\", root);\n//     return 0;\n// }","handlingStrategy":"validation","validationCode":"// Validate root path before traversal:\n// if (!FileSystem.Directory.Exists(root)) {\n//     logger.LogWarning(\"Traversal root does not exist: {Root}\", root);\n//     return 0;\n// }","typeGuard":null,"tryCatchPattern":"// try {\n//     var count = directoryService.TraverseTreeParallelForEach(root, action, searchPattern, logger);\n// } catch (ArgumentException ex) when (ex.Message.Contains(\"directory doesn't exist\")) {\n//     logger.LogWarning(\"Skipping traversal; root missing: {Root}\", root);\n//     return;\n// }","preventionTips":["Check directory existence before scheduling traversal tasks","Cancel pending scan tasks when a library root is removed","Validate volume mounts in container deployments before triggering library scans"],"tags":["filesystem","directory","not-found","argument","parallel-traversal"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}