Kareadita/Kavita · error · ArgumentException

The directory doesn't exist

Error message

The directory doesn't exist

What it means

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.

Source

Thrown at Kavita.Services/DirectoryService.cs:797

    /// up processing.
    /// NOTE: This is no longer parallel due to user's machines locking up
    /// </summary>
    /// <param name="root">Directory to scan</param>
    /// <param name="action">Action to apply on file path</param>
    /// <param name="searchPattern">Regex pattern to search against</param>
    /// <param name="logger"></param>
    /// <exception cref="ArgumentException"></exception>
    public int TraverseTreeParallelForEach(string root, Action<string> action, string searchPattern, ILogger logger)
    {
        //Count of files traversed and timer for diagnostic output
        var fileCount = 0;


        // Data structure to hold names of subfolders to be examined for files.
        var dirs = new Stack<string>();

        if (!FileSystem.Directory.Exists(root)) {
            throw new ArgumentException("The directory doesn't exist");
        }

        dirs.Push(root);

        while (dirs.Count > 0) {
            var currentDir = dirs.Pop();
            IEnumerable<string> subDirs;
            string[] files;

            try {
                subDirs = GetDirectories(currentDir);
            }
            // Thrown if we do not have discovery permission on the directory.
            catch (UnauthorizedAccessException e) {
                logger.LogCritical(e, "Unauthorized access on {Directory}", currentDir);
                continue;
            }
            // Thrown if another process has deleted the directory after we retrieved its name.

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Validate the root path exists before calling TraverseTreeParallelForEach
  2. Check that the library root is properly mounted and accessible
  3. If the library was removed, cancel any pending scan tasks that reference its path
  4. Add a pre-flight check in the calling code to skip non-existent roots with a warning log

Example fix

// Pre-flight check in the caller:
// if (!FileSystem.Directory.Exists(root)) {
//     logger.LogWarning("Skipping scan; root does not exist: {Root}", root);
//     return 0;
// }
Defensive patterns

Strategy: validation

Validate before calling

// Validate root path before traversal:
// if (!FileSystem.Directory.Exists(root)) {
//     logger.LogWarning("Traversal root does not exist: {Root}", root);
//     return 0;
// }

Try / catch

// try {
//     var count = directoryService.TraverseTreeParallelForEach(root, action, searchPattern, logger);
// } catch (ArgumentException ex) when (ex.Message.Contains("directory doesn't exist")) {
//     logger.LogWarning("Skipping traversal; root missing: {Root}", root);
//     return;
// }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/b12c7819af37e0b3. Report an issue: GitHub.