astrid-runtime/astrid · error

{install_dir} is not writable — re-run with elevated permiss

Error message

{install_dir} is not writable — re-run with elevated permissions, or reinstall via Homebrew/cargo.

What it means

run_self_update resolves the directory containing the current executable and checks writability (is_writable_dir) before downloading and swapping in a new build. If the install directory is not writable by the current user, the update is refused with instructions to either elevate or reinstall through a package manager. This prevents a partially applied update that would leave a broken binary behind.

Source

Thrown at crates/astrid-cli/src/commands/self_update/mod.rs:618

        },
        UpdatePlan::DeferToManager { manager, how } => {
            println!(
                "{}",
                Theme::info(&format!(
                    "Astrid was installed via {manager}. Update it with:\n  {how}"
                ))
            );
            return Ok(());
        },
        UpdatePlan::ApplyInPlace => {},
    }

    let install_dir = exe
        .parent()
        .ok_or_else(|| anyhow::anyhow!("cannot resolve install directory for {}", exe.display()))?
        .to_path_buf();
    if !is_writable_dir(&install_dir) {
        bail!(
            "{} is not writable — re-run with elevated permissions, or reinstall via Homebrew/cargo.",
            install_dir.display()
        );
    }

    if !confirm(
        &format!(
            "Update Astrid v{CURRENT_VERSION} → v{version_str} in {}?",
            install_dir.display()
        ),
        args.yes,
    )? {
        println!("{}", Theme::dimmed("Update cancelled."));
        return Ok(());
    }

    let (_tmp_dir, extract_dir) = download_verify_extract(
        &client,

View on GitHub (pinned to affd8760f4)

Solutions

  1. Re-run the update with elevated permissions: `sudo -E astrid self update` (or an elevated shell on Windows).
  2. Prefer reinstalling/upgrading via Homebrew or cargo when the install is package-manager-managed.
  3. Move the installation to a user-writable location (e.g. ~/.local/bin) and ensure PATH points there, then self-update normally.

Example fix

// before
$ astrid self update
error: /usr/local/bin is not writable — re-run with elevated permissions...

// after
$ sudo astrid self update
# or
$ brew upgrade astrid
Defensive patterns

Strategy: validation

Validate before calling

let dir = std::env::current_exe()?.parent().unwrap().to_path_buf();
let probe = dir.join(".astrid-write-test");
if std::fs::write(&probe, b"").is_err() {
    eprintln!("{} is not writable; use sudo or a package manager", dir.display());
} else {
    let _ = std::fs::remove_file(&probe);
}

Try / catch

match run_self_update().await {
    Err(e) if e.to_string().contains("is not writable") => {
        eprintln!("Re-run with sudo or upgrade via brew/cargo.");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Executing `astrid self update` while the executable lives in a directory the user cannot write to, e.g. /usr/local/bin or C:\Program Files, without elevated privileges.

Common situations: Astrid was installed system-wide with sudo but is updated as a normal user; corporate-managed machines with read-only Program Files; Homebrew/cargo-managed installs where the user shouldn't self-update at all.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/f5ada17d50872e69. Report an issue: GitHub.