{"record":{"id":"4c8db99a47e3fe56","repo":"astral-sh/ruff","slug":"could-not-diff-paths","errorCode":null,"errorMessage":"Could not diff paths","messagePattern":"Could not diff paths","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_db/src/diagnostic/render/gitlab.rs","lineNumber":180,"sourceCode":"}\n\n/// Generate a unique fingerprint to identify a violation.\nfn fingerprint(diagnostic: &Diagnostic, project_path: &str, salt: u64) -> u64 {\n    let mut hasher = DefaultHasher::new();\n\n    salt.hash(&mut hasher);\n    diagnostic.name().hash(&mut hasher);\n    project_path.hash(&mut hasher);\n\n    hasher.finish()\n}\n\n/// Convert an absolute path to be relative to the specified project root.\nfn relativize_path_to<P: AsRef<Path>, R: AsRef<Path>>(path: P, project_root: R) -> String {\n    format!(\n        \"{}\",\n        pathdiff::diff_paths(&path, project_root)\n            .expect(\"Could not diff paths\")\n            .display()\n    )\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::diagnostic::{\n        DiagnosticFormat,\n        render::tests::{create_diagnostics, create_syntax_error_diagnostics},\n    };\n\n    const FINGERPRINT_FILTERS: [(&str, &str); 1] = [(\n        r#\"\"fingerprint\": \"[a-z0-9]+\",\"#,\n        r#\"\"fingerprint\": \"<redacted>\",\"#,\n    )];\n\n    #[test]\n    fn output() {","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ruff_db/src/diagnostic/render/gitlab.rs#L162-L198","documentation":"GitLab-format diagnostic rendering relativizes each path against the project root via pathdiff::diff_paths(&path, project_root).expect(\"Could not diff paths\"). diff_paths returns None only when the paths have incompatible Windows prefixes (e.g. different drive letters), so the renderer panics in exactly that case.","triggerScenarios":"Producing GitLab-format output where a diagnostic's file is on a different Windows drive than the project root - e.g. file D:\\src\\x.py with root C:\\repo - so no relative path between them exists.","commonSituations":"Windows environments resolving dependencies or arguments across drives; UNC roots mixed with drive-letter paths; absolute cross-drive paths passed in include/files arguments.","solutions":["Invoke ruff so files and project root share a drive; run from the same drive as the checked files","Pass file arguments relative to the project root instead of cross-drive absolute paths","If it still fires, report it - the renderer should fall back to the absolute path instead of panicking"],"exampleFix":"# before (panics: different drives)\nruff check --output-format gitlab D:\\src\\main.py  # run from C:\\repo\n\n# after (same drive, relative path)\ncd D:\\src && ruff check --output-format gitlab main.py","handlingStrategy":"validation","validationCode":"// Windows tooling: ensure inputs share the project root's drive before rendering\nconst { root } = require('path').parse(projectRoot);\nif (path.parse(file).root !== root) { useAbsolutePathInstead(); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run ruff from the same drive as the files being checked","Avoid cross-drive absolute paths in include/files arguments","Prefer relative paths for everything under the project root"],"tags":["windows","paths","gitlab-ci","output-format","panic"],"backgroundTag":"cross-drive-relative-path","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}