{"record":{"id":"447a26592e7eb30b","repo":"sxyazi/yazi","slug":"trash-not-supported","errorCode":null,"errorMessage":"Trash not supported","messagePattern":"Trash not supported","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"warning","filePath":"yazi-vfs/src/engine/sftp/sftp.rs","lineNumber":193,"sourceCode":"\t}\n\n\tasync fn symlink<S, F>(&self, original: S, _is_dir: F) -> io::Result<()>\n\twhere\n\t\tS: AsStrand,\n\t\tF: AsyncFnOnce() -> io::Result<bool>,\n\t{\n\t\tlet original = original.as_strand().encoded_bytes();\n\n\t\tOk(self.op().await?.symlink(original, self.path).await?)\n\t}\n\n\tasync fn symlink_metadata(&self) -> io::Result<yazi_fs::cha::Cha> {\n\t\tlet attrs = self.op().await?.lstat(self.path).await?;\n\t\tOk(Cha::try_from((self.path.file_name().unwrap_or_default(), &attrs))?.0)\n\t}\n\n\tasync fn trash(&self) -> io::Result<()> {\n\t\tErr(io::Error::new(io::ErrorKind::Unsupported, \"Trash not supported\"))\n\t}\n\n\t#[inline]\n\tfn url(&self) -> Url<'_> { self.url }\n}\n\nimpl<'a> Sftp<'a> {\n\tpub(super) async fn op(&self) -> io::Result<deadpool::managed::Object<Conn>> {\n\t\tself.pool.get().await.map_err(|e| match e {\n\t\t\tPoolError::Timeout(_) => io::Error::new(io::ErrorKind::TimedOut, e.to_string()),\n\t\t\tPoolError::Backend(e) => e,\n\t\t\te => io::Error::other(e.to_string()),\n\t\t})\n\t}\n}\n","sourceCodeStart":175,"sourceCodeEnd":209,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-vfs/src/engine/sftp/sftp.rs#L175-L209","documentation":"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.","triggerScenarios":"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.","commonSituations":"Users pressing the trash/delete keybinding on files in an SSH mount; sync tools replicating local trash semantics to remote paths.","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"],"exampleFix":"-- before\nvfs.trash(url) -- Unsupported on SFTP\n-- after\nif url:kind() == 'sftp' then\n  vfs.remove(url)\nelse\n  vfs.trash(url)\nend","handlingStrategy":"fallback","validationCode":"local supported = url:kind() == 'local' or url:kind() == 'archive' -- trash only makes sense locally\nif not supported then return vfs.remove(url) end","typeGuard":"fn is_local(url: &Url) -> bool { matches!(url, Url::Local { .. }) }","tryCatchPattern":"match file.trash().await {\n    Err(e) if e.kind() == io::ErrorKind::Unsupported => {\n        // remote: fall back to permanent delete\n        file.remove().await\n    }\n    r => r,\n}","preventionTips":["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"],"tags":["sftp","trash","unsupported","delete"],"backgroundTag":"operation-not-supported","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}