sxyazi/yazi · error · io::Error
Unsupported OS for trash operation
Error message
Unsupported OS for trash operation
What it means
`Local::trash()` (local.rs:222) moves a path to the OS trash via the `trash` crate. On `target_os = "android"` the operation is unconditionally rejected with `ErrorKind::Unsupported`, because Android has no freedesktop/macOS trash protocol the crate can use. macOS and other Unix/Windows targets take the `trash::delete` paths.
Source
Thrown at yazi-fs/src/engine/local/local.rs:222
{
tokio::fs::symlink_file(original, self.path).await
}
}
#[inline]
async fn symlink_metadata(&self) -> io::Result<Cha> {
Ok(Cha::new(
self.path.file_name().unwrap_or_default(),
tokio::fs::symlink_metadata(self.path).await?,
))
}
async fn trash(&self) -> io::Result<()> {
let path = self.path.to_owned();
tokio::task::spawn_blocking(move || {
#[cfg(target_os = "android")]
{
Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported OS for trash operation"))
}
#[cfg(target_os = "macos")]
{
use trash::{TrashContext, macos::{DeleteMethod, TrashContextExtMacos}};
let mut ctx = TrashContext::default();
ctx.set_delete_method(DeleteMethod::NsFileManager);
ctx.delete(path).map_err(io::Error::other)
}
#[cfg(all(not(target_os = "macos"), not(target_os = "android")))]
{
trash::delete(path).map_err(io::Error::other)
}
})
.await?
}
#[inline]
fn url(&self) -> Url<'_> { self.url }View on GitHub (pinned to 94abcfa92f)
Solutions
- On Android, offer permanent delete instead of trash (bind the remove/delete-without-trash action).
- Gate trash UI/actions with `#[cfg(not(target_os = "android"))]` or a runtime capability check so the action is not offered.
- If trash semantics are required on Android, implement an app-private trash folder yourself and route deletes there.
Example fix
// before local.trash().await?; // Err(Unsupported) on Android // after #[cfg(target_os = "android")] local.remove().await?; // permanent delete on Android #[cfg(not(target_os = "android"))] local.trash().await?;
Defensive patterns
Strategy: fallback
Validate before calling
#[cfg(target_os = "android")]
fn trash_supported() -> bool { false }
#[cfg(not(target_os = "android"))]
fn trash_supported() -> bool { true } Try / catch
match local.trash().await {
Ok(()) => {}
Err(e) if e.kind() == io::ErrorKind::Unsupported => {
// Android: fall back to permanent removal after user confirmation
}
Err(e) => return Err(e),
} Prevention
- Detect the platform up front and hide trash actions on Android builds.
- Bind delete-to-trash only on platforms where `trash_supported()` is true.
- Offer an explicit 'delete permanently' binding as the Android default.
When it happens
Trigger: Building yazi for Android (`aarch64-linux-android` target) and invoking any delete-to-trash action (default `d` keybinding or the trash plugin API) on any file.
Common situations: Running a Termux/build of yazi on Android; CI cross-compilation tests that execute trash code paths on an Android target.
Related errors
- trash is not supported on this platform
- bundled rust-lld setup requires a Unix host
- restore target already exists: {to:?}
- invalid trash item path
- trash item is not a directory
AI-assisted analysis of sxyazi/yazi@94abcfa92f (2026-08-16).
Data as JSON: /api/errors/6f8b213f00793898.
Report an issue: GitHub.