denoland/deno · error · AnyError
You don't have write permission to {} because it's owned by
Error message
You don't have write permission to {} because it's owned by root.
Consider updating deno through your package manager if its installed from it.
Otherwise run `deno upgrade` as root. What it means
Unix-specific follow-up to the write-permission check: the target executable is owned by uid 0 (root) while the current process is not root, so even with write bits set the replace would fail. The message recommends using the system package manager or running the upgrade as root. This is the classic 'installed via apt/brew-as-root into /usr/local' situation.
Source
Thrown at cli/tools/upgrade.rs:2026
"failed to get metadata of the current executable at '{}'",
current_exe_path.display()
)
})?;
return Ok(metadata.permissions());
};
let permissions = metadata.permissions();
if permissions.readonly() {
bail!(
"You do not have write permission to {}",
output_exe_path.display()
);
}
#[cfg(unix)]
if std::os::unix::fs::MetadataExt::uid(&metadata) == 0
&& !nix::unistd::Uid::effective().is_root()
{
bail!(
concat!(
"You don't have write permission to {} because it's owned by root.\n",
"Consider updating deno through your package manager if its installed from it.\n",
"Otherwise run `deno upgrade` as root.",
),
output_exe_path.display()
);
}
Ok(permissions)
}
fn check_exe(exe_path: &Path) -> Result<(), AnyError> {
let output = Command::new(exe_path)
.arg("-V")
.stderr(std::process::Stdio::inherit())
.output()
.with_context(|| format!("failed to run '{}'", exe_path.display()))?;
if !output.status.success() {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Run `sudo deno upgrade` if you intend the system-wide install to be updated.
- Better: reinstall deno under your user (e.g. `$HOME/.deno/bin`) and put that first in PATH, so upgrades need no root.
- If installed by a package manager (apt/homebrew-as-root), update via that package manager instead.
- Or `sudo chown $(id -u) <path>` to take ownership, then upgrade normally.
Example fix
# before deno upgrade # owned by root -> error # after (option A: root update) sudo deno upgrade # after (option B: user-local install) curl -fsSL https://deno.land/install.sh | sh # installs to ~/.deno/bin export PATH="$HOME/.deno/bin:$PATH"
Defensive patterns
Strategy: validation
Validate before calling
deno_bin="$(command -v deno)"
[ "$(stat -c %u "$deno_bin" 2>/dev/null)" = "0" ] && [ "$(id -u)" != 0 ] && { echo "root-owned install — use sudo or move to ~/.deno"; exit 1; }
deno upgrade Try / catch
deno upgrade 2>err.log || { grep -q 'owned by root' err.log && sudo deno upgrade; } Prevention
- Prefer user-local installs (~/.deno/bin first in PATH) so upgrades never need root.
- For system installs, update via the owning package manager instead of deno upgrade.
- In Dockerfiles, install deno as the runtime user, not root, when users will self-upgrade.
When it happens
Trigger: `deno upgrade` where the existing deno binary (or output path) is root-owned and the user is not root — typically because it was installed with sudo (curl|sh into /usr/local/bin) or by a system package, triggering the uid-0 check at cli/tools/upgrade.rs:2026.
Common situations: Servers/containers where deno was installed as root and later used by a normal user; shared machines; Docker images baking deno as root; users following install docs that pipe curl to sudo sh.
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
- temporary directory ancestor '{}' is owned by uid {}, not cu
- Native addon cache directory '{}' is not owned by the curren
- You do not have write permission to {}
- temporary directory ancestor '{}' is writable by other users
- '{}' is owned by uid {}, not current uid {}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/154d4bb5990dba98.
Report an issue: GitHub.