rust-lang/mdBook · error

ignore root canonicalize error

Error message

ignore root canonicalize error

What it means

In poller.rs `new`, the gitignore root is canonicalized with `.expect("ignore root canonicalize error")` — same guard as native.rs. Failure (missing dir, broken symlink, Windows canonicalize quirk per PR #2229) panics while constructing the poller.

Source

Thrown at src/cmd/watch/poller.rs:113

impl Watcher {
    fn new(book_root: &Path) -> Watcher {
        // FIXME: ignore should be reloaded when it changes.
        let ignore = super::find_gitignore(book_root).map(|gitignore_path| {
            let (ignore, err) = Gitignore::new(&gitignore_path);
            if let Some(err) = err {
                warn!(
                    "error reading gitignore `{}`: {err}",
                    gitignore_path.display()
                );
            }
            // 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).
            let ignore_path = ignore
                .path()
                .canonicalize()
                .expect("ignore root canonicalize error");
            (ignore_path, ignore)
        });

        Watcher {
            ignore,
            ..Default::default()
        }
    }

    /// Sets the root directories where scanning will start.
    fn set_roots(&mut self, book: &MDBook) {
        let mut root_paths = vec![
            book.source_dir(),
            book.theme_dir(),
            book.root.join("book.toml"),
        ];
        root_paths.extend(
            book.config

View on GitHub (pinned to dc21064fc2)

Solutions

  1. Ensure the book root exists and is a resolvable path before `mdbook watch`.
  2. Run watch from a local (not network/UNC) path on Windows.
  3. Patch to fall back: `canonicalize().unwrap_or_else(|_| ignore.path().to_path_buf())`.
  4. Upgrade mdbook to a release that softens this canonicalize expect.

Example fix

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

Strategy: fallback

Validate before calling

let p = ignore.path();
if !p.exists() {
    eprintln!("cannot start watcher: ignore root {:?} missing", p);
    std::process::exit(1);
}
let _ = p.canonicalize()?; // fail early, not via expect

Try / catch

let ignore_path = ignore.path().canonicalize().unwrap_or_else(|e| {
    log::warn!("ignore root canonicalize failed: {e}");
    ignore.path().to_path_buf()
});

Prevention

When it happens

Trigger: Creating the WatchLater/Poller during `mdbook watch` when the directory backing the gitignore (`ignore.path()`) cannot be canonicalized: directory removed between parse and poller construction, invalid symlink, Windows-specific canonicalize failure (UNC/network paths).

Common situations: Book root deleted or renamed right as watch starts; race where book dir is temporarily unmounted; Windows network drives.

Related errors


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