can1357/oh-my-pi · error · io::Error
entry name contains NUL
Error message
entry name contains NUL
What it means
stat_entry converts a directory-entry name (raw bytes from getdents) into a CString for statx; an interior NUL makes conversion impossible, so it returns InvalidInput with this message. Entry names should never contain NUL on a healthy filesystem, so this guards against corrupt directory data or memory-safety hazards from passing the name to libc.
Source
Thrown at crates/pi-walker/src/lib.rs:3839
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "path contains NUL"))?;
// SAFETY: `path` is a NUL-terminated C string; flags request a directory
// descriptor used only with getdents/statx and do not retain the pointer.
let fd =
unsafe { libc::open(path.as_ptr(), libc::O_RDONLY | libc::O_DIRECTORY | libc::O_CLOEXEC) };
if fd < 0 {
Err(io::Error::last_os_error())
} else {
Ok(FdGuard(fd))
}
}
fn stat_entry(
dirfd: libc::c_int,
name: &[u8],
detail: WalkDetail,
) -> io::Result<Option<EntryStat>> {
let name = CString::new(name)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "entry name contains NUL"))?;
match statx_entry(dirfd, &name, detail) {
Ok(value) => Ok(value),
Err(err) if matches!(err.raw_os_error(), Some(libc::ENOSYS | libc::EINVAL)) => {
fstatat_entry(dirfd, &name, detail)
},
Err(err) => Err(err),
}
}
fn statx_entry(
dirfd: libc::c_int,
name: &CString,
detail: WalkDetail,
) -> io::Result<Option<EntryStat>> {
// SAFETY: `Statx` is a plain-old-data buffer whose all-zero value is a
// valid initialization before the kernel fills it.
let mut statx = unsafe { zeroed::<Statx>() };
let mask = if detail == WalkDetail::Full {View on GitHub (pinned to 9690622007)
Solutions
- Investigate the filesystem or mount producing entries with NUL in names (corruption, FUSE bug).
- Skip or report such entries: catch InvalidInput and continue the walk instead of failing the whole traversal.
- If fuzz-testing, treat this as expected validation behavior and assert on it rather than fixing the walker.
Defensive patterns
Strategy: try-catch
Try / catch
// walker callback
Err(e) if e.kind() == io::ErrorKind::InvalidInput => {
// entry name corrupt; skip entry, continue walk
ReadDirControl::Continue
} Prevention
- Treat entries with invalid names as filesystem corruption signals.
- Check the health of exotic mounts (FUSE/network) before deep walks.
- Prefer per-entry error handling so one bad entry doesn't abort traversal.
When it happens
Trigger: A directory stream yields an entry whose raw name bytes include 0x00, then the walker attempts statx/fstatat metadata lookup on that entry.
Common situations: Traversing a corrupted or synthetic filesystem, fuzzing the walker, or reading directory data from a misbehaving FUSE/overlay mount.
Related errors
- path contains NUL
- secret placeholder key at ${keyPath} is invalid
- source deps tree has no node_modules (${depsDir}); delete it
- unknown filetype: {ft_debug}
- Is a directory
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2b8bb19554e10603.
Report an issue: GitHub.