sxyazi/yazi · error · io::Error
trash item is not a directory
Error message
trash item is not a directory
What it means
Returned by Trash::list on macOS when it is called with Some(entry) whose lcha (link metadata) says the item is not a directory. Trash listing is hierarchical: only directories can be expanded, so asking for the children of a trashed file is an invalid-input error (io::ErrorKind::InvalidInput).
Source
Thrown at yazi-fs/src/trash/macos/trash.rs:15
use std::{fs, io, path::{Path, PathBuf}};
use yazi_macro::ok_or_not_found;
use super::{super::{TrashCha, TrashEntries, TrashEntry, TrashId, restore_item}, DsStore};
use crate::{cha::Cha, file::File};
pub struct Trash;
impl Trash {
pub(crate) fn new() -> io::Result<Self> { Ok(Self) }
pub(crate) fn list(&self, entry: Option<&TrashEntry>) -> io::Result<Vec<TrashEntry>> {
if entry.is_some_and(|entry| !entry.lcha.is_dir()) {
return Err(io::Error::new(io::ErrorKind::InvalidInput, "trash item is not a directory"));
}
let root = self.root()?;
let store = if entry.is_none() {
DsStore::parse(&root.join(".DS_Store")).unwrap_or_default()
} else {
Default::default()
};
let path = entry.map_or(&root, |entry| &entry.backing);
let it = match fs::read_dir(path) {
Ok(it) => it,
Err(e) if e.kind() == io::ErrorKind::NotFound && entry.is_none() => return Ok(vec![]),
Err(e) => return Err(e),
};
it.map(|dent| {
let dent = dent?;View on GitHub (pinned to 94abcfa92f)
Solutions
- Only call list with nil (trash root) or with an entry whose lcha.is_dir() is true.
- In UI flows, gate 'enter directory' on the entry kind, not on the current tab mode.
- Re-fetch the entry (Trash:entry) if the cached lcha may be stale, then re-check is_dir().
Example fix
-- Lua: before
local items = ya.fs("trash"):list(entry)
-- after
local trash = ya.fs("trash")
local items = entry and entry.lcha.is_dir and trash:list(entry) or trash:list() Defensive patterns
Strategy: type-guard
Validate before calling
-- Lua: only expand real directories (lcha = non-followed metadata)
if entry == nil or entry.lcha.is_dir then
local items = ya.fs("trash"):list(entry)
end Type guard
local function is_trash_dir(e) return e ~= nil and e.lcha ~= nil and e.lcha.is_dir == true end
Try / catch
local items, err = ya.fs("trash"):list(entry)
if items == nil and err.kind == "invalid-input" then
-- hovered item is a file: open/peek it instead of expanding
end Prevention
- Gate 'enter' in trash tabs on lcha.is_dir, not on tab mode.
- Refresh entries with Trash:entry before expanding when the view may be stale.
- Remember lcha (not cha) governs traversal: symlinks to dirs are not expandable here.
When it happens
Trigger: Trash:list(entry) / the Lua Trash:list with a file entry, e.g. pressing enter or expanding a regular file (or a symlink to a file, since lcha is the non-followed metadata) inside the trash view.
Common situations: Plugin or keymap that unconditionally calls list on the hovered trash item; hover state raced (entry became a file after a revalidate); trying to 'open' a file in trash as if it were a folder.
Related errors
- trash item is not a directory
- invalid trash entry path
- item is not in the trash
- invalid trash item path
- trash item has no put-back location
AI-assisted analysis of sxyazi/yazi@94abcfa92f (2026-08-16).
Data as JSON: /api/errors/40b8ebb70b320012.
Report an issue: GitHub.