{"record":{"id":"81cba17ade00dff5","repo":"sxyazi/yazi","slug":"invaliddata","errorCode":"InvalidData","errorMessage":"invalid original trash path","messagePattern":"invalid original trash path","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/trash/freedesktop/trash_info.rs","lineNumber":37,"sourceCode":"\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"invalid trash info path\"));\n\t\t}\n\n\t\t// /home/alice/.local/share/Trash\n\t\tlet root = info\n\t\t\t.parent()\n\t\t\t.filter(|p| p.file_name() == Some(OsStr::new(\"info\")))\n\t\t\t.and_then(Path::parent)\n\t\t\t.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"invalid trash info path\"))?;\n\n\t\t// cat.jpg\n\t\tlet stem = info\n\t\t\t.file_stem()\n\t\t\t.filter(|&stem| stem != OsStr::new(\".\") && stem != OsStr::new(\"..\"))\n\t\t\t.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"invalid trash info path\"))?;\n\n\t\tlet original = Self::parse_original(info, root)?;\n\t\tif original.file_name().is_none() {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"invalid original trash path\"));\n\t\t}\n\n\t\tOk(Self { root: root.to_owned(), backing: root.join(\"files\").join(stem), original })\n\t}\n\n\tfn parse_original(info: &Path, root: &Path) -> io::Result<PathBuf> {\n\t\tlet mut reader = BufReader::new(File::open(info)?);\n\t\tlet mut line = Vec::new();\n\n\t\treader.read_until(b'\\n', &mut line)?;\n\t\tSelf::trim_line(&mut line);\n\t\tif line != b\"[Trash Info]\" {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"invalid trash info header\"));\n\t\t}\n\n\t\tloop {\n\t\t\tline.clear();\n\t\t\tif reader.read_until(b'\\n', &mut line)? == 0 {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/sxyazi/yazi/blob/5f901b886b14de1f17460b6e52e9de5d67f8aba9/yazi-fs/src/trash/freedesktop/trash_info.rs#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (inside cat.jpg.trashinfo)\nPath=/\n// after\nPath=/home/alice/Pictures/cat.jpg","handlingStrategy":"validation","validationCode":"fn original_path_is_restorable(p: &std::path::Path) -> bool {\n    p.file_name().is_some() && p.as_os_str() != \"/\"\n}","typeGuard":null,"tryCatchPattern":"match TrashInfo::parse(&info_path) {\n    Ok(info) => restore(info),\n    Err(e) if e.to_string().contains(\"invalid original trash path\") => eprintln!(\"unrestorable entry, original path is degenerate\"),\n    Err(e) => return Err(e.into()),\n}","preventionTips":["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."],"tags":["filesystem","trash","path-validation","freedesktop"],"backgroundTag":"invalid-original-trash-path","analyzedSha":"5f901b886b14de1f17460b6e52e9de5d67f8aba9","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}