{"record":{"id":"0c7229347c25f0da","repo":"sxyazi/yazi","slug":"item-is-not-in-the-trash","errorCode":null,"errorMessage":"item is not in the trash","messagePattern":"item is not in the trash","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/trash/macos/trash.rs","lineNumber":50,"sourceCode":"\t\tit.map(|dent| {\n\t\t\tlet dent = dent?;\n\t\t\tif let Some(entry) = entry {\n\t\t\t\tentry.child(dent.file_name())\n\t\t\t} else {\n\t\t\t\tlet path = dent.path();\n\t\t\t\tlet original = store\n\t\t\t\t\t.get(path.file_name().unwrap_or_default())\n\t\t\t\t\t.and_then(|ds| ds.join(Path::new(\"\")).ok());\n\t\t\t\tTrashEntry::top(path.clone(), path, original)\n\t\t\t}\n\t\t})\n\t\t.collect()\n\t}\n\n\tpub(crate) fn entry(&self, id: &TrashId) -> io::Result<TrashEntry> {\n\t\tlet root = self.root()?;\n\t\tif id.top().parent() != Some(&root) {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidInput, \"item is not in the trash\"));\n\t\t}\n\t\tif id.has_rel() && !fs::symlink_metadata(id.top())?.file_type().is_dir() {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidInput, \"trash item is not a directory\"));\n\t\t}\n\n\t\tlet store = DsStore::parse(&root.join(\".DS_Store\")).unwrap_or_default();\n\t\tlet name = id.top().file_name().unwrap_or_default();\n\t\tlet original = store.get(name).and_then(|ds| ds.join(id.rel()).ok());\n\n\t\tTrashEntry::new(id.clone(), id.path(), original)\n\t}\n\n\tpub(crate) fn metadata(&self, entry: &TrashEntry, follow: bool) -> io::Result<Cha> {\n\t\tOk(if follow { entry.cha } else { entry.lcha })\n\t}\n\n\tpub(crate) fn revalidate(\n\t\t&self,","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/sxyazi/yazi/blob/94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2/yazi-fs/src/trash/macos/trash.rs#L32-L68","documentation":"Returned by Trash::entry on macOS when the TrashId's top path is not a direct child of the trash root (~/.Trash). The macOS backend models trash as top-level items under ~/.Trash plus a relative path inside them; an id whose top lives anywhere else is rejected with io::ErrorKind::InvalidInput.","triggerScenarios":"Calling Trash:entry with a hand-built Lua table { top = '/Users/me/some/path', rel = '' } where top.parent() != ~/.Trash; using a filesystem path instead of an id obtained from Trash:list; HOME resolution changed between listing and lookup so the roots disagree.","commonSituations":"Plugins constructing ids from Urls or strings instead of reusing entries from list(); ids persisted across sessions after HOME moved; passing a nested path (e.g. ~/.Trash/dir/file) as top instead of top=~/.Trash/dir with rel=file.","solutions":["Always obtain ids from Trash:list/Trash:entry results instead of constructing them manually.","If building by hand, set top to an absolute path directly inside ~/.Trash and put deeper segments in rel.","Verify HOME is stable (dirs::home_dir must resolve to the same absolute root) across the call."],"exampleFix":"-- Lua: before (nested path as top)\nlocal e = ya.fs(\"trash\"):entry({ top = \"/Users/me/.Trash/Project/a.txt\", rel = \"\" })\n-- after (top is direct child of ~/.Trash, rest is rel)\nlocal e = ya.fs(\"trash\"):entry({ top = \"/Users/me/.Trash/Project\", rel = \"a.txt\" })","handlingStrategy":"validation","validationCode":"-- Lua: verify top is a direct child of ~/.Trash before lookup\nlocal home = ya.claim_to_be_home -- or obtain HOME from ya\nlocal root = \"/Users/\" .. ya.user_name .. \"/.Trash\" -- better: reuse top from a listed entry\nlocal function top_in_trash(top)\n  return top:sub(1, #root + 1) == root .. \"/\" and not top:find(\"/\", #root + 2)\nend","typeGuard":"local function is_valid_trash_id(t)\n  return type(t) == \"table\"\n    and type(t.top) == \"string\" and #t.top > 0\n    and type(t.rel) == \"string\" and t.rel:sub(1, 1) ~= \"/\"\nend","tryCatchPattern":"local e, err = ya.fs(\"trash\"):entry(id)\nif e == nil and err.kind == \"invalid-input\" then\n  -- id was hand-built: re-list and match by name instead of retrying\nend","preventionTips":["Always source ids from list()/entry() results; never synthesize them from Urls.","Keep top = direct child of ~/.Trash and move deeper segments into rel.","Ensure HOME is unchanged between listing and lookup."],"tags":["trash","macos","invalid-input","trash-id","lookup"],"backgroundTag":null,"analyzedSha":"94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2","analyzedAt":"2026-08-16T09:56:24.836Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}