{"record":{"id":"8ffeac7790f67653","repo":"sxyazi/yazi","slug":"invalid-trash-item-path","errorCode":null,"errorMessage":"invalid trash item path","messagePattern":"invalid trash item path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"yazi-fs/src/trash/entry.rs","lineNumber":43,"sourceCode":"\tfn deref(&self) -> &Self::Target { &self.id }\n}\n\nimpl TrashEntry {\n\t#[cfg(trash_unix)]\n\tpub(super) fn new<B>(id: TrashId, backing: B, original: Option<PathBuf>) -> io::Result<Self>\n\twhere\n\t\tB: Into<PathBuf>,\n\t{\n\t\tuse super::TrashCha;\n\t\tlet backing = backing.into();\n\n\t\tlet name = id\n\t\t\t.rel()\n\t\t\t.file_name()\n\t\t\t.or_else(|| original.as_deref().and_then(Path::file_name))\n\t\t\t.or_else(|| backing.file_name())\n\t\t\t.filter(|name| !name.is_empty())\n\t\t\t.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, \"invalid trash item path\"))?;\n\n\t\tlet (lcha, cha) = Cha::from_trash(&backing, name)?;\n\t\tlet link_to = if lcha.is_link() { std::fs::read_link(&backing).ok() } else { None };\n\n\t\tOk(Self { id, cha, lcha, original, link_to, backing })\n\t}\n\n\t#[cfg(trash_unix)]\n\tpub(super) fn top<T, B>(top: T, backing: B, original: Option<PathBuf>) -> io::Result<Self>\n\twhere\n\t\tT: Into<PathBuf>,\n\t\tB: Into<PathBuf>,\n\t{\n\t\tSelf::new(TrashId::new(top, PathBuf::new())?, backing, original)\n\t}\n\n\t#[cfg(trash_unix)]\n\tpub(super) fn child(&self, name: OsString) -> io::Result<Self> {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/sxyazi/yazi/blob/5f901b886b14de1f17460b6e52e9de5d67f8aba9/yazi-fs/src/trash/entry.rs#L25-L61","documentation":"TrashEntry::new derives the item's display name by taking file_name() from the trashed id's rel path, the recorded original path, or the backing path, and rejects empty names. If none of these yields a non-empty file name (e.g. the path terminates in \"..\" or \"/\", or all candidates are empty), it returns InvalidInput \"invalid trash item path\". The trash entry cannot be represented without a name.","triggerScenarios":"Constructing TrashEntry from a trash id whose rel path and original path have no file component and whose backing path also has none (root-ish or trailing-separator paths); corrupted trash records with an empty original path.","commonSituations":"Manually edited or corrupted .trashinfo files (empty Path= line); ids built programmatically from a root path or a path ending in '..'; trash directories tampered with outside the app.","solutions":["Inspect the trash record (.trashinfo file or id) and fix/remove entries with empty or malformed original paths.","Ensure the id/rel path passed to the trash API points at an actual entry, not a root or trailing-separator path.","Clear the affected trash directory (empty trash) so the corrupt record is removed, then re-scan."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Rust\nfn has_file_name(p: &Path) -> bool {\n    p.file_name().map_or(false, |n| !n.is_empty())\n}","typeGuard":null,"tryCatchPattern":"match TrashEntry::new(id, ...) {\n    Err(e) if e.to_string().contains(\"invalid trash item path\") => skip_entry_and_log(id),\n    other => other?,\n}","preventionTips":["Never build trash ids from root or trailing-separator paths.","Validate .trashinfo records (non-empty Path=) before ingesting them.","Skip corrupt trash records instead of failing the whole listing."],"tags":["trash","path","invalid-input","validation"],"backgroundTag":"invalid-trash-item-path","analyzedSha":"5f901b886b14de1f17460b6e52e9de5d67f8aba9","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}