rust-lang/mdBook · error

ignore root canonicalize error

Error message

ignore root canonicalize error

What it means

In native.rs `filter_ignored_files`, the gitignore root path is canonicalized with `.expect("ignore root canonicalize error")`, so if `Path::canonicalize` fails (typically because the ignore root does not exist, or on Windows where canonicalize is flaky per PR #2229 discussion) the program panics. The comment in the source explicitly flags the Windows fragility risk.

Solutions

  1. Ensure the book root (where .gitignore lives) exists and is accessible before running `mdbook watch`.
  2. Avoid running watch against paths on network drives / UNC paths on Windows.
  3. Replace the `.expect` with graceful handling, e.g. fall back to the non-canonicalized path.
  4. Update mdbook to a version where watch ignore handling tolerates canonicalize failure.

Example fix

// before
let ignore_root = ignore.path().canonicalize().expect("ignore root canonicalize error");
// after
let ignore_root = ignore
    .path()
    .canonicalize()
    .unwrap_or_else(|_| ignore.path().to_path_buf());
Defensive patterns

Strategy: fallback

Validate before calling

let ignore_root_raw = ignore.path();
if !ignore_root_raw.exists() {
    eprintln!("ignore root missing: {:?}", ignore_root_raw);
    std::process::exit(1);
}
let canonical = ignore_root_raw.canonicalize(); // check Result before depending on it

Try / catch

// expect() panics, so guard at the boundary:
let ignore_root = ignore.path().canonicalize().unwrap_or_else(|e| {
    log::warn!("canonicalize failed ({e}); using raw path");
    ignore.path().to_path_buf()
});

Prevention

When it happens

Trigger: `mdbook watch` building its ignore filter when `ignore.path()` (the directory the .gitignore was loaded from) cannot be canonicalized: the directory was deleted/moved after parsing, a broken symlink, or a Windows canonicalize failure (network drives, case/path-form quirks).

Common situations: Watching a book directory that gets renamed or removed while watch is running; book root on a network/UNC path on Windows; symlinked book roots.

Related errors


AI-assisted analysis of rust-lang/mdBook@dc21064fc2 (2026-09-01). Data as JSON: /api/errors/789e5ee8afaf2b2a. Report an issue: GitHub.

Appendix: source

Thrown at src/cmd/watch/native.rs:136

                    gitignore_path.display()
                );
            }
            filter_ignored_files(ignore, paths)
        }
        None => {
            // There is no .gitignore file.
            paths.iter().map(|path| path.to_path_buf()).collect()
        }
    }
}

// Note: The usage of `canonicalize` may encounter occasional failures on the Windows platform, presenting a potential risk.
// For more details, refer to [Pull Request #2229](https://github.com/rust-lang/mdBook/pull/2229#discussion_r1408665981).
fn filter_ignored_files(ignore: Gitignore, paths: &[PathBuf]) -> Vec<PathBuf> {
    let ignore_root = ignore
        .path()
        .canonicalize()
        .expect("ignore root canonicalize error");

    paths
        .iter()
        .filter(|path| {
            let relative_path = pathdiff::diff_paths(&path, &ignore_root)
                .expect("One of the paths should be an absolute");
            !ignore
                .matched_path_or_any_parents(&relative_path, relative_path.is_dir())
                .is_ignore()
        })
        .map(|path| path.to_path_buf())
        .collect()
}

#[cfg(test)]
mod tests {
    use super::*;
    use ignore::gitignore::GitignoreBuilder;

View on GitHub (pinned to dc21064fc2)