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

  1. Run `sudo deno upgrade` if you intend the system-wide install to be updated.
  2. Better: reinstall deno under your user (e.g. `$HOME/.deno/bin`) and put that first in PATH, so upgrades need no root.
  3. If installed by a package manager (apt/homebrew-as-root), update via that package manager instead.
  4. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/154d4bb5990dba98. Report an issue: GitHub.