sxyazi/yazi · error

Invalid filename attribute

Error message

Invalid filename attribute

What it means

On macOS, casefold::final_name reads a filename attribute via getattrlist and validates the returned buffer's bounds and NUL-terminated C string. If the offsets/length in the attribute buffer don't describe a valid in-bounds NUL-terminated name, it throws 'Invalid filename attribute'.

Solutions

  1. Retry the lookup — the file may have changed between calls
  2. Check the filesystem type; use APFS/HFS+ which support case-insensitive name recovery
  3. Fall back to a directory-listing case match when the attribute is unavailable

Example fix

// before
let name = buf.get(..len)...ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Invalid filename attribute"))?;
// after
let name = match buf.get(..len).and_then(|b| b.get(start as usize..end as usize)).and_then(|b| CStr::from_bytes_with_nul(b).ok()) {
    Some(n) => n,
    None => return fallback_list_dir_case_match(path), // graceful fallback
};
Defensive patterns

Strategy: fallback

Validate before calling

// macOS only; verify the fs supports the attribute before trusting it
fn supports_returned_attrs() -> bool { std::env::consts::OS == "macos" }

Type guard

fn valid_name_attr(buf: &[u8], len: usize) -> Option<&std::ffi::CStr> {
    let start = 4 + i32::from_ne_bytes(buf[4..8].try_into().ok()?) as usize;
    let end = start + u32::from_ne_bytes(buf[8..12].try_into().ok()?) as usize;
    buf.get(..len)?.get(start..end).and_then(|b| std::ffi::CStr::from_bytes_with_nul(b).ok())
}

Try / catch

match Casefold::final_name(path) {
    Ok(name) => name,
    Err(_) => scan_parent_dir_for_case_match(path).unwrap_or_else(|_| path.as_os_str().to_owned()),
}

Prevention

When it happens

Trigger: The getattrlist ATTR_CMN_RETURNED_ATTRS buffer layout is unexpected — wrong buffer size, kernel returns fewer bytes, or offsets point outside the buffer.

Common situations: Running on macOS versions where the attribute layout differs; filesystems (non-APFS/HFS+) that don't fully support the attribute; racing file deletion between the call and attribute read.

Related errors


AI-assisted analysis of sxyazi/yazi@a541adde4e (2026-09-18). Data as JSON: /api/errors/b23372e562dfb432. Report an issue: GitHub.

Appendix: source

Thrown at yazi-fs/src/casefold/macos.rs:39

		nonneg_ok(unsafe {
			libc::getattrlist(
				path.as_ptr(),
				(&raw mut attrs).cast(),
				buf.as_mut_ptr().cast(),
				buf.len(),
				libc::FSOPT_NOFOLLOW as _,
			)
		})?;

		// The name offset is relative to the attrreference following the length word.
		let len = u32::from_ne_bytes(buf[..4].try_into().unwrap()) as usize;
		let start = 4 + i32::from_ne_bytes(buf[4..8].try_into().unwrap()) as i64;
		let end = start + u32::from_ne_bytes(buf[8..12].try_into().unwrap()) as i64;
		let name = buf
			.get(..len)
			.and_then(|b| b.get(start as usize..end as usize))
			.and_then(|b| CStr::from_bytes_with_nul(b).ok())
			.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Invalid filename attribute"))?;

		Ok(OsString::from_vec(name.to_bytes().to_vec()))
	}
}

View on GitHub (pinned to a541adde4e)