sinelaw/fresh · error · SudoSaveRequired
SudoSaveRequired
Error message
SudoSaveRequired
What it means
An in-place save could not write the destination file directly because the process lacks the file owner's privileges (uid/gid/mode mismatch). save.rs:569 raises the structured SudoSaveRequired error (via make_sudo_error, from save_with_inplace_write or write_data_inplace) carrying temp_path, dest_path, uid, gid, and mode so the caller can retry the save with elevated (sudo) privileges.
Solutions
- Handle the SudoSaveRequired payload: complete the save using the provided temp_path and elevate (e.g. sudo install -m mode -o uid -g gid temp_path dest_path)
- Reopen the editor with elevated privileges (sudo fresh file) for system-owned files
- Change ownership/permissions of the file (sudo chown) so your user can write it in place
- Save to a writable copy instead of the privileged original
Defensive patterns
Strategy: try-catch
Validate before calling
// Unix: check write ownership before attempting in-place save
let meta = std::fs::metadata(&dest_path)?;
let i_am_owner = unsafe { libc::geteuid() } == meta.uid();
if !i_am_owner { prepare_sudo_save_flow(&dest_path); } Try / catch
// downcast to the structured error
match editor.save(buffer_id) {
Err(e) if e.downcast_ref::<SudoSaveRequired>().is_some() => {
let s = e.downcast_ref::<SudoSaveRequired>().unwrap();
sudo_complete_save(&s.temp_path, &s.dest_path, s.uid, s.gid, s.mode);
}
other => other?,
} Prevention
- Check file ownership/permissions before opening system files for editing
- Run the editor with adequate privileges (sudo) when editing root-owned files
- Detect the SudoSaveRequired error type and implement the elevated-save handoff in your integration
When it happens
Trigger: Editing a file owned by root (or another user) as a non-root process and saving in place — the write requires the file's uid/gid/mode to be preserved but the process isn't the owner.
Common situations: Editing /etc config files or root-owned project files in a normal user session; files created by a container as root then edited by the host user; NFS/ACL setups where the effective uid differs from the file owner.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- sudo tee failed
- sudo tee failed
- TypeScript plugin thread creation failed
- this build was compiled without self-update support…
- Line indexing not available for this document
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/dfcc8dd48e90b592.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor-core/src/model/buffer/save.rs:569
#[cfg(unix)]
let (uid, gid, mode) = if let Some(ref meta) = original_metadata {
(
meta.uid.unwrap_or(0),
meta.gid.unwrap_or(0),
meta.permissions
.as_ref()
.map(|p| p.mode() & 0o7777)
.unwrap_or(0),
)
} else {
(0, 0, 0)
};
#[cfg(not(unix))]
let (uid, gid, mode) = (0u32, 0u32, 0u32);
let _ = original_metadata; // suppress unused warning on non-Unix
anyhow::anyhow!(SudoSaveRequired {
temp_path,
dest_path: dest_path.to_path_buf(),
uid,
gid,
mode,
})
}
View on GitHub (pinned to 67894ca546)