jdx/mise · error · eyre::Report

{} failed

Error message

{} failed

What it means

sudo::run executes an elevated command via sudo (with a pre_exec fchdir restoring the caller's cwd) and checks the exit status; on failure it bails with the full argv, which includes env assignments injected by the wrapper. Interactive callers are expected to hold a sudo timestamp from a prior `sudo -v`, so a failure here means sudoers policy rejected the command or the elevated command itself exited non-zero.

Source

Thrown at src/system/sudo.rs:157

    let raw = dir.as_fd().as_raw_fd();
    let mut cmd = Command::new(&argv[0]);
    cmd.args(&argv[1..]);
    // SAFETY: `fchdir` is async-signal-safe and only alters the child's working
    // directory. `raw` stays open in the parent across the spawn, and CLOEXEC
    // (if set) only takes effect at exec, after pre_exec has run.
    unsafe {
        cmd.pre_exec(move || {
            if nix::libc::fchdir(raw) == -1 {
                return Err(std::io::Error::last_os_error());
            }
            Ok(())
        });
    }
    let status = cmd
        .status()
        .wrap_err_with(|| format!("failed to run {}", argv.join(" ")))?;
    if !status.success() {
        bail!("{} failed", argv.join(" "));
    }
    Ok(())
}

/// Run an elevated command and capture its output.
///
/// Interactive callers authenticate with an inherited `sudo -v` first so a
/// password prompt is never hidden inside captured stderr. Non-interactive
/// callers retain [`ensure_elevation_available`]'s fail-fast `sudo -n` check.
pub(crate) fn output(program: &str, args: &[String], envs: &[(String, String)]) -> Result<Output> {
    let argv = argv_with_env(program, args, envs);
    let manual_cmd = std::iter::once("sudo".to_string())
        .chain((!envs.is_empty()).then_some("env".to_string()))
        .chain(envs.iter().map(|(key, value)| format!("{key}={value}")))
        .chain(std::iter::once(program.to_string()))
        .chain(args.iter().cloned())
        .collect::<Vec<_>>()
        .join(" ");

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Run `sudo -v` interactively immediately before, or configure NOPASSWD for the elevated helper in sudoers
  2. Copy the printed argv and run it manually to see the real exit status and stderr
  3. Check sudoers covers every privileged subcommand mise invokes
  4. Fix the underlying failure of the elevated command once identified from its output
Defensive patterns

Strategy: try-catch

Validate before calling

// Before a batch of elevated operations, confirm sudo will not block or deny
fn elevation_ready() -> Result<()> {
    let status = Command::new("sudo").arg("-n").arg("-v").status()?;
    if !status.success() {
        bail!("sudo credentials unavailable; run `sudo -v` interactively first");
    }
    Ok(())
}

Try / catch

match sudo::run(&program, &args, &envs) {
    Err(err) => {
        let msg = err.to_string();
        if let Some(argv) = msg.strip_suffix(" failed") {
            // argv names the exact elevated command; re-run it manually to inspect the real failure
        }
        return Err(err);
    }
    ok => ok,
}

Prevention

When it happens

Trigger: Non-interactive runs using `sudo -n` after the timestamp expired; sudoers rules that deny or do not whitelist the specific command; the privileged bootstrap step failing on a real system error.

Common situations: CI/cron without NOPASSWD configured for mise's elevated helper; hardened sudoers whitelists missing one subcommand; privileged apply failing due to underlying system state (disk, permissions).

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/ce1958d8c72f5112. Report an issue: GitHub.