rust-lang/mdBook · error
One of the paths should be an absolute
Error message
One of the paths should be an absolute
What it means
`filter_ignored_files` computes each event path relative to the canonicalized ignore root using `pathdiff::diff_paths` and unwraps with `.expect("One of the paths should be an absolute")`. diff_paths returns None when both paths can't be made relative (e.g. one relative and one absolute, or differing Windows prefixes/drives), and this expect turns that into a panic.
Source
Thrown at src/cmd/watch/native.rs:142
// 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;
use std::env;
#[test]
fn test_filter_ignored_files() {
let current_dir = env::current_dir().unwrap();
View on GitHub (pinned to dc21064fc2)
Solutions
- Canonicalize event paths before diffing (poller.rs does exactly this: `path.canonicalize().unwrap_or_else(|_| path.to_path_buf())`).
- Keep the book and its .gitignore on the same drive/prefix on Windows.
- Replace the expect with a `filter_map`/`unwrap_or` that skips or retains the path when diff_paths returns None.
- Check for symlinked book roots producing non-matching path prefixes.
Example fix
// before
let relative_path = pathdiff::diff_paths(&path, &ignore_root)
.expect("One of the paths should be an absolute");
// after
let Some(relative_path) = pathdiff::diff_paths(&path, &ignore_root) else {
return true; // keep path when it cannot be made relative to ignore root
}; Defensive patterns
Strategy: fallback
Validate before calling
// pre-check before diffing
fn diffable(path: &Path, root: &Path) -> bool {
path.is_absolute() == root.is_absolute()
&& path.components().next() == root.components().next() // same prefix/drive
} Try / catch
let relative_path = match pathdiff::diff_paths(&path, &ignore_root) {
Some(p) => p,
None => return true, // or skip, instead of panicking
}; Prevention
- Canonicalize both sides (event path and ignore root) before diffing.
- Keep book tree and .gitignore on the same Windows drive/prefix.
- Avoid symlinked book roots that break prefix equality.
- Replace diff_paths expects with Option handling in watch code.
When it happens
Trigger: A watch-event path and the canonicalized ignore root live under different drives/prefixes (Windows C: vs D:, UNC vs drive), or an event path is relative while the ignore root is absolute, so `diff_paths(path, ignore_root)` returns None.
Common situations: Windows cross-drive book/ignore locations; notify event paths delivered in a different form than the canonicalized root; symlinked directories causing prefix mismatch.
Related errors
- ignore root canonicalize error
- One of the paths should be an absolute
- ignore root canonicalize error
- Unable to determine the current directory
- expected a file, `{}` appears to be {:?}
AI-assisted analysis of rust-lang/mdBook@dc21064fc2 (2026-09-01).
Data as JSON: /api/errors/535ffed0a8f2b9ed.
Report an issue: GitHub.