sxyazi/yazi · warning · io::Error
Trash not supported
Error message
Trash not supported
What it means
The SFTP backend does not implement move-to-trash: remote filesystems have no trash concept, so `trash()` unconditionally returns ErrorKind::Unsupported. Callers must treat trash as unavailable for remote locations and delete explicitly or skip the operation.
Source
Thrown at yazi-vfs/src/engine/sftp/sftp.rs:193
}
async fn symlink<S, F>(&self, original: S, _is_dir: F) -> io::Result<()>
where
S: AsStrand,
F: AsyncFnOnce() -> io::Result<bool>,
{
let original = original.as_strand().encoded_bytes();
Ok(self.op().await?.symlink(original, self.path).await?)
}
async fn symlink_metadata(&self) -> io::Result<yazi_fs::cha::Cha> {
let attrs = self.op().await?.lstat(self.path).await?;
Ok(Cha::try_from((self.path.file_name().unwrap_or_default(), &attrs))?.0)
}
async fn trash(&self) -> io::Result<()> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Trash not supported"))
}
#[inline]
fn url(&self) -> Url<'_> { self.url }
}
impl<'a> Sftp<'a> {
pub(super) async fn op(&self) -> io::Result<deadpool::managed::Object<Conn>> {
self.pool.get().await.map_err(|e| match e {
PoolError::Timeout(_) => io::Error::new(io::ErrorKind::TimedOut, e.to_string()),
PoolError::Backend(e) => e,
e => io::Error::other(e.to_string()),
})
}
}
View on GitHub (pinned to 8ebf930f17)
Solutions
- Delete permanently instead: call the remove/delete API rather than trash for SFTP URLs
- Gate the operation on URL kind — check the file is local before offering trash
- Catch the Unsupported error and surface a 'trash is not supported on remote files' message to the user
- Configure the client to disable trash for remote mounts so the unsupported path is never hit
Example fix
-- before vfs.trash(url) -- Unsupported on SFTP -- after if url:kind() == 'sftp' then vfs.remove(url) else vfs.trash(url) end
Defensive patterns
Strategy: fallback
Validate before calling
local supported = url:kind() == 'local' or url:kind() == 'archive' -- trash only makes sense locally if not supported then return vfs.remove(url) end
Type guard
fn is_local(url: &Url) -> bool { matches!(url, Url::Local { .. }) } Try / catch
match file.trash().await {
Err(e) if e.kind() == io::ErrorKind::Unsupported => {
// remote: fall back to permanent delete
file.remove().await
}
r => r,
} Prevention
- Check the URL kind and disable trash for remote mounts in your UI/config
- Always have a permanent-delete fallback for unsupported backends
- Surface a clear 'trash not supported on remote' notice instead of a raw error
- Keep delete flows abstracted behind the VFS so backend capability differences are handled in one place
When it happens
Trigger: Any delete-with-trash request on an SFTP-backed file/folder — e.g. the file manager's delete command (with trash enabled) targeting a remote entry.
Common situations: Users pressing the trash/delete keybinding on files in an SSH mount; sync tools replicating local trash semantics to remote paths.
Related errors
AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02).
Data as JSON: /api/errors/447a26592e7eb30b.
Report an issue: GitHub.