lsd-rs/lsd · error · std::io::Error
invalid file name
Error message
invalid file name
What it means
recurse_into walks a directory and calls Path::file_name() on each entry's path. When a path ends in '..' or is a bare root with no final component, file_name() returns None, and this InvalidInput io::Error is produced instead of a usable entry name. It indicates a malformed or degenerate directory entry encountered during recursion, not a user-facing listing problem.
Source
Thrown at src/meta/mod.rs:125
)?;
"..".clone_into(&mut parent_meta.name.name);
current_meta.git_status = cache.and_then(|cache| cache.get(¤t_meta.path, true));
parent_meta.git_status = cache.and_then(|cache| cache.get(&parent_meta.path, true));
content.push(current_meta);
content.push(parent_meta);
}
let mut exit_code = ExitCode::OK;
for entry in entries {
let entry = entry?;
let path = entry.path();
let name = path
.file_name()
.ok_or_else(|| Error::new(ErrorKind::InvalidInput, "invalid file name"))?;
if flags.ignore_globs.0.is_match(name) {
continue;
}
#[cfg(windows)]
let is_hidden =
name.to_string_lossy().starts_with('.') || windows_utils::is_path_hidden(&path);
#[cfg(not(windows))]
let is_hidden = name.to_string_lossy().starts_with('.');
#[cfg(windows)]
let is_system = windows_utils::is_path_system(&path);
#[cfg(not(windows))]
let is_system = false;
match flags.display {
// show hidden files, but ignore system protected filesView on GitHub (pinned to 4b6c14a110)
Solutions
- Check the path you are recursing into: avoid passing paths ending in '..' or bare roots ('/') to the walker.
- Skip or normalize degenerate paths before recursion (e.g. canonicalize, or use entry.file_name()/entry.path().file_name on the DirEntry rather than re-derived paths).
- Handle the io::Error at the call site and continue with the remaining entries instead of aborting the whole listing.
- If it reproduces on ordinary directories, verify the filesystem/mount is not returning malformed entries (dmesg, fsck).
Example fix
// before
recurse_into("/some/dir/..")?; // panics/errors: file_name() == None
// after
let path = fs::canonicalize("/some/dir/..")?; // normalizes '..'
recurse_into(&path)?; Defensive patterns
Strategy: validation
Validate before calling
fn has_file_name(p: &std::path::Path) -> bool {
p.file_name().is_some() // false for "/", "dir/.."
}
// before recursing: if !has_file_name(&path) { skip } Type guard
fn safe_file_name(p: &std::path::Path) -> Option<&std::ffi::OsStr> {
p.file_name()
} Try / catch
match walker_result {
Ok(entries) => /* use entries */,
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => /* skip path, continue */,
Err(e) => return Err(e),
} Prevention
- Normalize paths with canonicalize() before passing them to recursive walkers.
- Never pass paths ending in '..' or bare roots ('/') into directory recursion.
- Prefer entry.file_name()/DirEntry-derived names over re-deriving from joined paths.
- Filter out root and parent components early in custom walkers.
When it happens
Trigger: Calling recursion/listing APIs (which enter recurse_into) over a directory whose entries include paths lacking a final component — e.g. paths constructed as "dir/.." or root paths like "/" or "C:\" fed back into the walker, or a directory entry whose OsStr cannot yield a file_name.
Common situations: Recursing into mount points or symlink loops that resolve to '/' or '..'; pointing eza at the filesystem root; custom VFS/FUSE mounts yielding odd entries; scripting that passes paths ending in '/..' into a recursive listing.
Related errors
AI-assisted analysis of lsd-rs/lsd@4b6c14a110 (2026-09-04).
Data as JSON: /api/errors/9729084f5c583a91.
Report an issue: GitHub.