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
During `scan`, poller.rs canonicalizes each directory-entry path (falling back to the raw path on failure) and then calls `diff_paths(&path, &ignore_path).expect("One of the paths should be an absolute")`. If the entry path cannot be made relative to the canonicalized ignore root — different drive/prefix, differing canonical forms — diff_paths yields None and the expect panics the watcher.
Source
Thrown at src/cmd/watch/poller.rs:171
fn scan(&mut self) -> Vec<PathBuf> {
let ignore = &self.ignore;
let new_path_data: HashMap<_, _> = self
.root_paths
.iter()
.filter(|root| root.exists())
.flat_map(|root| {
WalkDir::new(root)
.follow_links(true)
.into_iter()
.filter_entry(|entry| {
if let Some((ignore_path, ignore)) = ignore {
let path = entry.path();
// Canonicalization helps with removing `..` and
// `.` entries, which can cause issues with
// diff_paths.
let path = path.canonicalize().unwrap_or_else(|_| path.to_path_buf());
let relative_path = diff_paths(&path, &ignore_path)
.expect("One of the paths should be an absolute");
if ignore
.matched_path_or_any_parents(&relative_path, relative_path.is_dir())
.is_ignore()
{
trace!("ignoring {path:?}");
return false;
}
}
true
})
.filter_map(move |entry| {
let entry = match entry {
Ok(e) => e,
Err(e) => {
debug!("failed to scan {root:?}: {e}");
return None;
}
};View on GitHub (pinned to dc21064fc2)
Solutions
- Keep the entire book tree on the same drive/prefix as its .gitignore.
- Handle diff_paths None gracefully: `match diff_paths(...) { Some(r) => ..., None => return true }` instead of expect.
- Ensure the ignore_path cached in `new` is still valid/canonical relative to scanned entries.
- Remove broken symlinks from the watched tree or exclude them from scanning.
Example fix
// before
let relative_path = diff_paths(&path, &ignore_path)
.expect("One of the paths should be an absolute");
// after
let Some(relative_path) = diff_paths(&path, &ignore_path) else {
trace!("could not relativize {path:?} against {ignore_path:?}");
return true;
}; Defensive patterns
Strategy: fallback
Validate before calling
// before scanning, ensure entry relativizes against the cached root
if diff_paths(&entry.path().canonicalize().unwrap_or_else(|_| entry.path().to_path_buf()), &ignore_path).is_none() {
trace!("skipping path outside ignore root prefix");
} Try / catch
let Some(relative_path) = diff_paths(&path, &ignore_path) else {
trace!("diff_paths returned None for {path:?}");
return true; // treat as not-ignored rather than panic
}; Prevention
- Canonicalize each scanned entry (as poller.rs already does) before diffing.
- Keep the whole watched tree on one drive/prefix on Windows.
- Exclude or clean up broken symlinks in the watched tree.
- Handle diff_paths None explicitly instead of expect.
When it happens
Trigger: A scanned file path resolves to a different drive/UNC prefix than the canonicalized ignore root on Windows; canonicalize fails on an entry (broken symlink) leaving a path form incompatible with the ignore root; ignore root changed identity after being cached in the poller.
Common situations: Windows cross-drive setups; symlinked book subdirectories; files whose canonicalization fails (deleted mid-scan) while the root is canonical, producing None from diff_paths.
Related errors
- One of the paths should be an absolute
- ignore root canonicalize error
- 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/e99029746c6abed5.
Report an issue: GitHub.