{"record":{"id":"535ffed0a8f2b9ed","repo":"rust-lang/mdBook","slug":"one-of-the-paths-should-be-an-absolute","errorCode":null,"errorMessage":"One of the paths should be an absolute","messagePattern":"One of the paths should be an absolute","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/watch/native.rs","lineNumber":142,"sourceCode":"            // There is no .gitignore file.\n            paths.iter().map(|path| path.to_path_buf()).collect()\n        }\n    }\n}\n\n// Note: The usage of `canonicalize` may encounter occasional failures on the Windows platform, presenting a potential risk.\n// For more details, refer to [Pull Request #2229](https://github.com/rust-lang/mdBook/pull/2229#discussion_r1408665981).\nfn filter_ignored_files(ignore: Gitignore, paths: &[PathBuf]) -> Vec<PathBuf> {\n    let ignore_root = ignore\n        .path()\n        .canonicalize()\n        .expect(\"ignore root canonicalize error\");\n\n    paths\n        .iter()\n        .filter(|path| {\n            let relative_path = pathdiff::diff_paths(&path, &ignore_root)\n                .expect(\"One of the paths should be an absolute\");\n            !ignore\n                .matched_path_or_any_parents(&relative_path, relative_path.is_dir())\n                .is_ignore()\n        })\n        .map(|path| path.to_path_buf())\n        .collect()\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use ignore::gitignore::GitignoreBuilder;\n    use std::env;\n\n    #[test]\n    fn test_filter_ignored_files() {\n        let current_dir = env::current_dir().unwrap();\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/rust-lang/mdBook/blob/dc21064fc21d955a0e1f67e65e336883c3e5260b/src/cmd/watch/native.rs#L124-L160","documentation":"`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.","triggerScenarios":"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.","commonSituations":"Windows cross-drive book/ignore locations; notify event paths delivered in a different form than the canonicalized root; symlinked directories causing prefix mismatch.","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."],"exampleFix":"// before\nlet relative_path = pathdiff::diff_paths(&path, &ignore_root)\n    .expect(\"One of the paths should be an absolute\");\n// after\nlet Some(relative_path) = pathdiff::diff_paths(&path, &ignore_root) else {\n    return true; // keep path when it cannot be made relative to ignore root\n};","handlingStrategy":"fallback","validationCode":"// pre-check before diffing\nfn diffable(path: &Path, root: &Path) -> bool {\n    path.is_absolute() == root.is_absolute()\n        && path.components().next() == root.components().next() // same prefix/drive\n}","typeGuard":null,"tryCatchPattern":"let relative_path = match pathdiff::diff_paths(&path, &ignore_root) {\n    Some(p) => p,\n    None => return true, // or skip, instead of panicking\n};","preventionTips":["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."],"tags":["filesystem","panic","pathdiff","windows","watch"],"backgroundTag":"relative-path-conversion-failed","analyzedSha":"dc21064fc21d955a0e1f67e65e336883c3e5260b","analyzedAt":"2026-09-01T10:15:12.134Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}