sxyazi/yazi · error

invalid trash item path

Error message

invalid trash item path

What it means

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.

Solutions

  1. Inspect the trash record (.trashinfo file or id) and fix/remove entries with empty or malformed original paths.
  2. Ensure the id/rel path passed to the trash API points at an actual entry, not a root or trailing-separator path.
  3. Clear the affected trash directory (empty trash) so the corrupt record is removed, then re-scan.
Defensive patterns

Strategy: validation

Validate before calling

// Rust
fn has_file_name(p: &Path) -> bool {
    p.file_name().map_or(false, |n| !n.is_empty())
}

Try / catch

match TrashEntry::new(id, ...) {
    Err(e) if e.to_string().contains("invalid trash item path") => skip_entry_and_log(id),
    other => other?,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/8ffeac7790f67653. Report an issue: GitHub.

Appendix: source

Thrown at yazi-fs/src/trash/entry.rs:43

	fn deref(&self) -> &Self::Target { &self.id }
}

impl TrashEntry {
	#[cfg(trash_unix)]
	pub(super) fn new<B>(id: TrashId, backing: B, original: Option<PathBuf>) -> io::Result<Self>
	where
		B: Into<PathBuf>,
	{
		use super::TrashCha;
		let backing = backing.into();

		let name = id
			.rel()
			.file_name()
			.or_else(|| original.as_deref().and_then(Path::file_name))
			.or_else(|| backing.file_name())
			.filter(|name| !name.is_empty())
			.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "invalid trash item path"))?;

		let (lcha, cha) = Cha::from_trash(&backing, name)?;
		let link_to = if lcha.is_link() { std::fs::read_link(&backing).ok() } else { None };

		Ok(Self { id, cha, lcha, original, link_to, backing })
	}

	#[cfg(trash_unix)]
	pub(super) fn top<T, B>(top: T, backing: B, original: Option<PathBuf>) -> io::Result<Self>
	where
		T: Into<PathBuf>,
		B: Into<PathBuf>,
	{
		Self::new(TrashId::new(top, PathBuf::new())?, backing, original)
	}

	#[cfg(trash_unix)]
	pub(super) fn child(&self, name: OsString) -> io::Result<Self> {

View on GitHub (pinned to 5f901b886b)