rust-lang/rust · error · io::Error
File path is invalid: {path}
Error message
File path is invalid: {path} What it means
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.
Source
Thrown at src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs:112
}
/// Copy the dylib to temp directory to prevent locking in Windows
#[cfg(windows)]
fn ensure_file_with_lock_free_access(
temp_dir: &TempDir,
path: &Utf8Path,
) -> io::Result<Utf8PathBuf> {
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hasher};
if std::env::var("RA_DONT_COPY_PROC_MACRO_DLL").is_ok() {
return Ok(path.to_path_buf());
}
let mut to = Utf8Path::from_path(temp_dir.path()).unwrap().to_owned();
let file_name = path.file_stem().ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}"))
})?;
to.push({
// Generate a unique number by abusing `HashMap`'s hasher.
// Maybe this will also "inspire" a libs team member to finally put `rand` in libstd.
let unique_name = RandomState::new().build_hasher().finish();
format!("{file_name}-{unique_name}.dll")
});
fs::copy(path, &to)?;
Ok(to)
}
#[cfg(unix)]
fn ensure_file_with_lock_free_access(
_temp_dir: &TempDir,
path: &Utf8Path,
) -> io::Result<Utf8PathBuf> {
Ok(path.to_owned())View on GitHub (pinned to 7088e4b63a)
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.
Example fix
// Diagnostic: print the path before loading.
println!("dylib path = {:?}", path);
assert!(path.file_stem().is_some(), "path has no file stem");
// Then rebuild: cargo clean -p my-crate && cargo build Defensive patterns
Strategy: validation
Validate before calling
fn valid_dylib_path(path: &std::path::Path) -> io::Result<()> {
match path.file_stem() {
Some(_) => Ok(()),
None => Err(io::Error::new(io::ErrorKind::InvalidInput,
format!("path has no file stem: {path:?}"))),
}
} Type guard
fn has_file_stem(p: &std::path::Path) -> bool {
p.file_stem().map(|s| !s.is_empty()).unwrap_or(false)
} Try / catch
match ensure_file_with_lock_free_access(&tmp, &path) {
Ok(p) => Ok(p),
Err(e) if e.kind() == io::ErrorKind::InvalidInput
&& e.to_string().contains("File path is invalid") => {
// clean & rebuild the crate, then retry load
Err(e)
}
Err(e) => Err(e),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- File does not exist {!r}
- closed
- proc-macro server did not respond with data
- proc-macro-srv-cli needs to be compiled with the `in-rust-tr
- rust-analyzer Language Server is not available. Please, ensu
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/9b3b49378293c74f.
Report an issue: GitHub.