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(&current_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 files

View on GitHub (pinned to 4b6c14a110)

Solutions

  1. Check the path you are recursing into: avoid passing paths ending in '..' or bare roots ('/') to the walker.
  2. 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).
  3. Handle the io::Error at the call site and continue with the remaining entries instead of aborting the whole listing.
  4. 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

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.