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.

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)

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.