sxyazi/yazi · error
Missing filename
Error message
Missing filename
What it means
The Unix casefold implementation needs both the parent directory and the file name component to statat() the exact name. If the path has no parent (bare relative name) or no file_name (trailing slash / '.' / '..'), it returns 'Missing filename'.
Solutions
- Ensure the path passed to final_name points to an actual file, not a directory or root
- Strip trailing separators before calling
- Canonicalize the path first so components are well-formed
Example fix
// before
Casefold::final_name(Path::new("/"))?
// after
if path.file_name().is_none() { return Err(...); }
Casefold::final_name(path)? Defensive patterns
Strategy: validation
Validate before calling
fn has_file_component(path: &std::path::Path) -> bool {
path.parent().is_some() && path.file_name().is_some()
} Type guard
fn split_parent_name(path: &Path) -> Option<(&Path, &std::ffi::OsStr)> {
path.parent().zip(path.file_name())
} Try / catch
match Casefold::final_name(path) {
Ok(n) => n,
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => return path.as_os_str().to_owned(),
Err(e) => return Err(e.into()),
} Prevention
- Reject root/"."/trailing-slash paths before lookup
- Canonicalize paths to normalize components
- Only call final_name on concrete file paths from listings
When it happens
Trigger: Calling Casefold::final_name with a path like '/', './', 'foo/', or a bare 'file' that has no parent component.
Common situations: Passing root or directory URLs with trailing separators into the casefold lookup; constructing paths programmatically that lost their file component.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Failed to join new name with CWD
- invalid file type
- Invalid filename attribute
- atime not available
- btime not available
AI-assisted analysis of sxyazi/yazi@a541adde4e (2026-09-18).
Data as JSON: /api/errors/0db92e804c710b2a.
Report an issue: GitHub.
Appendix: source
Thrown at yazi-fs/src/casefold/unix.rs:13
use std::{ffi::{OsStr, OsString}, io::{self, ErrorKind}, os::{fd::AsFd, unix::ffi::OsStrExt}, path::Path};
use rustix::fs::{AtFlags, FileType, Mode, OFlags, Stat, open, statat};
use super::Casefold;
use crate::scanner::Scanner;
impl Casefold {
pub(super) fn final_name(path: &Path) -> io::Result<OsString> {
let (parent, name) = path
.parent()
.zip(path.file_name())
.ok_or_else(|| io::Error::new(ErrorKind::InvalidInput, "Missing filename"))?;
let parent = if parent.as_os_str().is_empty() { Path::new(".") } else { parent };
let fd = open(parent, OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, Mode::empty())?;
let meta = statat(&fd, name, AtFlags::SYMLINK_NOFOLLOW)?;
if Self::case_sensitive(&fd) == Some(true) {
Ok(name.to_owned())
} else if Self::is_same_mount(&fd, name) {
Self::scan_fast(name, &fd, meta)
} else {
Self::scan_full(name, &fd, meta)
}
}
fn scan_fast(name: &OsStr, fd: &impl AsFd, stat: Stat) -> io::Result<OsString> {
let mut names = vec![];
Scanner::visit(&fd, |n, ino| {
let n = OsStr::from_bytes(n.to_bytes());View on GitHub (pinned to a541adde4e)