{"record":{"id":"3c6483169d6bd4cd","repo":"sxyazi/yazi","slug":"invalidinput-3c6483","errorCode":"InvalidInput","errorMessage":"trash item is not a directory","messagePattern":"trash item is not a directory","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/trash/macos/trash.rs","lineNumber":15,"sourceCode":"use std::{fs, io, path::{Path, PathBuf}};\n\nuse yazi_macro::ok_or_not_found;\n\nuse super::{super::{TrashCha, TrashEntries, TrashEntry, TrashId, restore_item}, DsStore};\nuse crate::{cha::Cha, file::File};\n\npub struct Trash;\n\nimpl Trash {\n\tpub(crate) fn new() -> io::Result<Self> { Ok(Self) }\n\n\tpub(crate) fn list(&self, entry: Option<&TrashEntry>) -> io::Result<Vec<TrashEntry>> {\n\t\tif entry.is_some_and(|entry| !entry.lcha.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 root = self.root()?;\n\t\tlet store = if entry.is_none() {\n\t\t\tDsStore::parse(&root.join(\".DS_Store\")).unwrap_or_default()\n\t\t} else {\n\t\t\tDefault::default()\n\t\t};\n\n\t\tlet path = entry.map_or(&root, |entry| &entry.backing);\n\t\tlet it = match fs::read_dir(path) {\n\t\t\tOk(it) => it,\n\t\t\tErr(e) if e.kind() == io::ErrorKind::NotFound && entry.is_none() => return Ok(vec![]),\n\t\t\tErr(e) => return Err(e),\n\t\t};\n\n\t\tit.map(|dent| {\n\t\t\tlet dent = dent?;","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-fs/src/trash/macos/trash.rs#L1-L33","documentation":"Trash::list on macOS enumerates the children of a trashed directory; it requires the given entry to actually be a directory (checked via the entry's lcha cached cha). Calling list with a trashed file entry is an invalid input.","triggerScenarios":"Calling Trash::list(Some(entry)) where entry.lcha.is_dir() is false — i.e. listing contents of a trashed regular file, symlink, or other non-directory.","commonSituations":"Caller listed the trash, picked an entry without checking its kind, and tried to recurse into it; UI code hovering a trashed file and requesting its children.","solutions":["Check entry.lcha.is_dir() before calling list","Call list with None to list the trash root instead","Handle the error and treat the file entry as childless"],"exampleFix":"// before\nlet children = trash.list(Some(&entry))?;\n// after\nlet children = if entry.lcha.is_dir() { trash.list(Some(&entry))? } else { Vec::new() };","handlingStrategy":"validation","validationCode":"if entry.lcha.is_dir() { trash.list(Some(entry))?; }","typeGuard":"fn is_trashed_dir(entry: &TrashEntry) -> bool { entry.lcha.is_dir() }","tryCatchPattern":"match trash.list(Some(entry)) {\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput => Vec::new(), // non-directory: no children\n    other => other?,\n}","preventionTips":["Check lcha.is_dir() before listing children","Treat non-directory trash entries as leaf nodes","Reuse the entry's cached cha instead of re-statting"],"tags":["macos","trash","io","invalid-input"],"backgroundTag":"not-a-directory","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}