sxyazi/yazi · error · io::Error
InvalidData
InvalidData
Error message
invalid original trash path
What it means
After reading the Path= key from the .trashinfo file, parse validates that the recorded original path has a file name component. If Path= points at a directory root or a path ending in ".."/"." (file_name() is None), restoring is impossible and this InvalidData error is returned. It guards against malformed or degenerate entries in trash metadata.
Source
Thrown at yazi-fs/src/trash/freedesktop/trash_info.rs:37
return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid trash info path"));
}
// /home/alice/.local/share/Trash
let root = info
.parent()
.filter(|p| p.file_name() == Some(OsStr::new("info")))
.and_then(Path::parent)
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "invalid trash info path"))?;
// cat.jpg
let stem = info
.file_stem()
.filter(|&stem| stem != OsStr::new(".") && stem != OsStr::new(".."))
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "invalid trash info path"))?;
let original = Self::parse_original(info, root)?;
if original.file_name().is_none() {
return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid original trash path"));
}
Ok(Self { root: root.to_owned(), backing: root.join("files").join(stem), original })
}
fn parse_original(info: &Path, root: &Path) -> io::Result<PathBuf> {
let mut reader = BufReader::new(File::open(info)?);
let mut line = Vec::new();
reader.read_until(b'\n', &mut line)?;
Self::trim_line(&mut line);
if line != b"[Trash Info]" {
return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid trash info header"));
}
loop {
line.clear();
if reader.read_until(b'\n', &mut line)? == 0 {View on GitHub (pinned to 5f901b886b)
Solutions
- Fix the Path= line in the .trashinfo file to the absolute original file path including its file name.
- Delete the malformed .trashinfo (and matching files/ entry) if the entry is unusable.
- Avoid trashing filesystem roots or "."/".." style paths; trash real files only.
- Verify percent-encoding of Path= is correct — e.g. "/" must be encoded as %2F per the spec.
Example fix
// before (inside cat.jpg.trashinfo) Path=/ // after Path=/home/alice/Pictures/cat.jpg
Defensive patterns
Strategy: validation
Validate before calling
fn original_path_is_restorable(p: &std::path::Path) -> bool {
p.file_name().is_some() && p.as_os_str() != "/"
} Try / catch
match TrashInfo::parse(&info_path) {
Ok(info) => restore(info),
Err(e) if e.to_string().contains("invalid original trash path") => eprintln!("unrestorable entry, original path is degenerate"),
Err(e) => return Err(e.into()),
} Prevention
- Never trash filesystem roots or paths ending in '.' / '..'.
- Keep Path= values as full absolute file paths including the file name.
- Percent-encode Path= values correctly ('/' as %2F) when writing .trashinfo files.
- Validate .trashinfo contents after any manual edit.
When it happens
Trigger: A .trashinfo file whose Path= value is "/", ends with a trailing component like "." or ".." (e.g. Path=%2F..), or was percent-encoded from an empty/root-like path.
Common situations: Hand-edited .trashinfo files; broken third-party trash implementations writing root paths; entries created by deleting a mount point or special directory; corrupted metadata after disk issues.
Related errors
- Cannot create file at root
- Target URL must be absolute
- Failed to join new name with parent directory
- trash item is not a directory
- trash item outside of trash folders
AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02).
Data as JSON: /api/errors/81cba17ade00dff5.
Report an issue: GitHub.