{"record":{"id":"f1b681200ab4fc8a","repo":"sxyazi/yazi","slug":"cannot-convert-attributes","errorCode":null,"errorMessage":"Cannot convert attributes","messagePattern":"Cannot convert attributes","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-vfs/src/engine/sftp/sftp.rs","lineNumber":172,"sourceCode":"\t\tmatch op.rename_posix(self.path, &to).await {\n\t\t\tOk(()) => {}\n\t\t\tErr(yazi_sftp::Error::Unsupported) => {\n\t\t\t\tmatch op.remove(&to).await.map_err(io::Error::from) {\n\t\t\t\t\tOk(()) => {}\n\t\t\t\t\tErr(e) if e.kind() == io::ErrorKind::NotFound => {}\n\t\t\t\t\tErr(e) => Err(e)?,\n\t\t\t\t}\n\t\t\t\top.rename(self.path, &to).await?;\n\t\t\t}\n\t\t\tErr(e) => Err(e)?,\n\t\t}\n\t\tOk(())\n\t}\n\n\tasync fn set_attrs(&self, attrs: yazi_fs::engine::Attrs) -> io::Result<()> {\n\t\tlet attrs = super::Attrs(attrs)\n\t\t\t.try_into()\n\t\t\t.map_err(|()| io::Error::new(io::ErrorKind::InvalidInput, \"Cannot convert attributes\"))?;\n\n\t\tOk(self.op().await?.setstat(self.path, attrs).await?)\n\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}","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-vfs/src/engine/sftp/sftp.rs#L154-L190","documentation":"`set_attrs` converts the engine-agnostic `yazi_fs::engine::Attrs` into SFTP `setstat` attributes; the TryFrom conversion returns `()` on failure, which is mapped to this InvalidInput error. It means the requested attribute set contains values the SFTP backend cannot represent or convert (e.g. unsupported or out-of-range fields), so nothing was sent to the server.","triggerScenarios":"Setting attributes (permissions, times, uid/gid) on a remote file where the provided Attrs cannot be translated into SFTP setstat fields — for example unsupported attribute kinds or values out of the protocol's range.","commonSituations":"Plugins applying local-only attributes to remote files, syncing metadata between a local and SFTP location where the local side has attributes SFTP lacks, or calling set_attrs with default/uninitialized Attrs.","solutions":["Inspect the Attrs being set and drop/normalize fields the SFTP backend doesn't support before calling","Validate permission/timestamp values (mode within 0o7777, sane times) on the caller side","Only call set_attrs on SFTP files with attributes sourced from that same remote (via stat/Cha)","Catch the error and degrade gracefully — attribute setting is usually optional"],"exampleFix":"-- before\nfile:set_attrs(all_attrs) -- may fail\n-- after\nlocal attrs = { perm = all_attrs.perm } -- only SFTP-representable fields\nlocal ok, err = pcall(file.set_attrs, file, attrs)","handlingStrategy":"validation","validationCode":"local attrs = { perm = 0o644, atime = os.time(), mtime = os.time() }\nassert(attrs.perm >= 0 and attrs.perm <= 0o7777, 'perm out of range for setstat')","typeGuard":null,"tryCatchPattern":"-- set_attrs is best-effort; degrade gracefully\nlocal ok, err = pcall(file.set_attrs, file, attrs)\nif not ok then\n  ya.dbg('attribute update skipped: '..tostring(err)) -- 'Cannot convert attributes'\nend","preventionTips":["Only set attributes obtained from the same remote (via stat/Cha), not from local files","Restrict Attrs to fields SFTP supports (perm, times); drop uid/gid or others when unsure","Range-check modes (0..0o7777) and timestamps before calling","Treat metadata propagation between local and remote as lossy — wrap in pcall/Result and continue"],"tags":["sftp","attrs","chmod","invalid-input"],"backgroundTag":"attrs-conversion-failed","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}