zeroclaw-labs/zeroclaw · error · anyhow::Error
cli-update-not-writable
cli-update-not-writable
Error message
install directory {$dir} is not writable ({$error}); re-run `zeroclaw update` with elevated privileges (sudo on macOS/Linux, an Administrator console on Windows) What it means
Before installing an update, ensure_install_dir_writable probes the install directory by creating a '.zeroclaw-update-probe-<pid>' file and deleting it. If creation fails, the update aborts with the directory, the underlying OS error, and the remediation hint to re-run with sudo (macOS/Linux) or an Administrator console (Windows). This error carries the stable code 'cli-update-not-writable'.
Source
Thrown at src/commands/update.rs:840
Some("x86")
} else if cfg!(target_arch = "arm") {
Some("arm")
} else {
None
}
}
async fn ensure_install_dir_writable(exe: &Path) -> Result<()> {
let dir = exe
.parent()
.context("cannot determine install directory for the current executable")?;
let probe = dir.join(format!(".zeroclaw-update-probe-{}", std::process::id()));
match tokio::fs::File::create(&probe).await {
Ok(_) => {
let _ = tokio::fs::remove_file(&probe).await;
Ok(())
}
Err(e) => bail!(install_dir_not_writable_message(
&dir.display().to_string(),
&e.to_string()
)),
}
}
#[cfg(not(windows))]
async fn swap_binary(new: &Path, target: &Path) -> Result<()> {
tokio::fs::remove_file(target)
.await
.context("failed to remove old binary")?;
tokio::fs::copy(new, target)
.await
.context("failed to write new binary")?;
Ok(())
}
#[cfg(windows)]View on GitHub (pinned to 88bb9c8533)
Solutions
- Re-run the update with elevated privileges exactly as the message suggests: `sudo zeroclaw update` on macOS/Linux or an Administrator console on Windows.
- For a user-owned setup instead: `sudo chown $(whoami) <install-dir>` so future updates need no elevation.
- Or move the binary to a user-writable directory already on PATH (e.g. ~/.local/bin) and update from there.
- If you expected the directory to be writable, check the embedded OS error for the real cause (read-only mount, deleted directory, ACL).
Example fix
# before: unprivileged update into root-owned dir fails zeroclaw update # -> install directory ... is not writable # after: elevate, or take ownership once sudo zeroclaw update sudo chown $(whoami) /usr/local/bin && zeroclaw update
Defensive patterns
Strategy: validation
Validate before calling
use std::fs;
fn install_dir_writable(dir: &std::path::Path) -> bool {
let probe = dir.join(format!(".zc-probe-{}", std::process::id()));
match fs::File::create(&probe) {
Ok(_) => { let _ = fs::remove_file(&probe); true }
Err(_) => false,
}
}
// call before running the update; if false, elevate or fix ownership first Try / catch
match run_update().await {
Err(e) if e.to_string().contains("is not writable") => {
// re-invoke with sudo (or fix dir ownership), then retry once
}
other => other,
} Prevention
- Install zeroclaw in a user-writable directory on PATH (~/.local/bin) to avoid elevation on every update.
- Or chown the install directory once: `sudo chown $(whoami) <dir>`.
- In automation, pre-check writability with a probe file before invoking the update command.
When it happens
Trigger: `zeroclaw update` when the directory holding the current zeroclaw binary is not writable by the invoking user: binary in /usr/local/bin owned by root, a read-only mount, a system-protected path, or (ENOENT variants) an install directory that no longer exists.
Common situations: Binary initially installed with sudo or by a package manager into a root-owned path; corporate lockdown with read-only /usr/local; running the update from an unprivileged service account.
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
- channel does not support room invites
- local IPC endpoint lock directory {} is owned by uid {}; it
- local IPC endpoint lock directory {} is writable by other us
- Unable to determine installed skill directory after clone (n
- Skill source must be a directory: {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/5c090363fbacb3a0.
Report an issue: GitHub.