{"record":{"id":"9b3b49378293c74f","repo":"rust-lang/rust","slug":"file-path-is-invalid-path","errorCode":null,"errorMessage":"File path is invalid: {path}","messagePattern":"File path is invalid: (.+?)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs","lineNumber":112,"sourceCode":"}\n\n/// Copy the dylib to temp directory to prevent locking in Windows\n#[cfg(windows)]\nfn ensure_file_with_lock_free_access(\n    temp_dir: &TempDir,\n    path: &Utf8Path,\n) -> io::Result<Utf8PathBuf> {\n    use std::collections::hash_map::RandomState;\n    use std::hash::{BuildHasher, Hasher};\n\n    if std::env::var(\"RA_DONT_COPY_PROC_MACRO_DLL\").is_ok() {\n        return Ok(path.to_path_buf());\n    }\n\n    let mut to = Utf8Path::from_path(temp_dir.path()).unwrap().to_owned();\n\n    let file_name = path.file_stem().ok_or_else(|| {\n        io::Error::new(io::ErrorKind::InvalidInput, format!(\"File path is invalid: {path}\"))\n    })?;\n\n    to.push({\n        // Generate a unique number by abusing `HashMap`'s hasher.\n        // Maybe this will also \"inspire\" a libs team member to finally put `rand` in libstd.\n        let unique_name = RandomState::new().build_hasher().finish();\n        format!(\"{file_name}-{unique_name}.dll\")\n    });\n    fs::copy(path, &to)?;\n    Ok(to)\n}\n\n#[cfg(unix)]\nfn ensure_file_with_lock_free_access(\n    _temp_dir: &TempDir,\n    path: &Utf8Path,\n) -> io::Result<Utf8PathBuf> {\n    Ok(path.to_owned())","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs#L94-L130","documentation":"Returned by proc-macro-srv's Windows-only ensure_file_with_lock_free_access when path.file_stem() returns None - i.e. the supplied library path has no valid file-name stem (empty, ends in '..', or is a root/directory path). std raises ErrorKind::InvalidInput with the offending path interpolated. The function exists to copy the proc-macro dylib to a temp dir so Windows does not lock the original.","triggerScenarios":"Loading a proc-macro dylib on Windows where the path passed to load_dylib has no file_stem: an empty string, a path ending in a separator, '..', or a volume root like \"C:\\\". Rust-analyzer invokes this when expanding macros from a crate whose dylib path is malformed.","commonSituations":"Corrupted/empty OUT_DIR or target dir producing a bad dylib path; a build script emitting a malformed path; symlinks resolving to a root; cargo metadata returning an anomalous path.","solutions":["Inspect the exact path value printed in the error - it has no file stem component.","Clean and rebuild the affected crate (cargo clean -p <crate> && cargo build) so target paths regenerate.","Verify the dylib actually exists at the expected target/<triple>/<profile>/ path before rust-analyzer loads it.","Report/check the cargo metadata if the path originates there; fix the build script producing an empty filename."],"exampleFix":"// Diagnostic: print the path before loading.\nprintln!(\"dylib path = {:?}\", path);\nassert!(path.file_stem().is_some(), \"path has no file stem\");\n// Then rebuild: cargo clean -p my-crate && cargo build","handlingStrategy":"validation","validationCode":"fn valid_dylib_path(path: &std::path::Path) -> io::Result<()> {\n    match path.file_stem() {\n        Some(_) => Ok(()),\n        None => Err(io::Error::new(io::ErrorKind::InvalidInput,\n            format!(\"path has no file stem: {path:?}\"))),\n    }\n}","typeGuard":"fn has_file_stem(p: &std::path::Path) -> bool {\n    p.file_stem().map(|s| !s.is_empty()).unwrap_or(false)\n}","tryCatchPattern":"match ensure_file_with_lock_free_access(&tmp, &path) {\n    Ok(p) => Ok(p),\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput\n        && e.to_string().contains(\"File path is invalid\") => {\n        // clean & rebuild the crate, then retry load\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Validate the dylib path has a file_stem before loading on Windows.","Clean and rebuild crates when target paths look malformed.","Log the exact path passed to load_dylib to catch empty/root paths early."],"tags":["rust-analyzer","proc-macro","windows","dylib","filesystem","path"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}