Morganamilo/paru · critical

failed to spawn auth process

Error message

failed to spawn auth process

What it means

`LazyPipe::run` failed to spawn the external authentication helper process; the spawn failure is wrapped with context 'failed to spawn auth process' and then cached (memoized) in the lazy pipe, so every subsequent `run` call reuses the same failure. This typically means the auth binary path in Config is wrong, the binary is missing, or it failed at exec time.

Solutions

  1. Fix `spawn_auth`: verify the auth helper binary path in Config exists and is executable
  2. Run the helper manually with the same args to see the underlying spawn error
  3. Clear/replace the cached failure (recreate the LazyPipe) after fixing, since the Err is memoized

Example fix

// before
let pipe = pipe.get_or_insert_with(|| spawn_auth(config).context("failed to spawn auth process"));
// after
let pipe = match pipe.get_or_insert_with(|| spawn_auth(config).context("failed to spawn auth process")) {
    Err(e) => bail!("auth process: {} (verify helper path in config)", e),
    Ok(p) => p,
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the auth helper before first use
fn verify_auth_helper(config: &Config) -> Result<()> {
    let path = config.auth_helper_path();
    ensure!(Path::new(&path).exists(), "auth helper missing: {}", path);
    ensure!(is_executable(&path), "auth helper not executable: {}", path);
    Ok(())
}

Try / catch

if let Err(e) = verify_auth_helper(&config) {
    eprintln!("{}; falling back to interactive auth", e);
    return interactive_auth(&config);
}
auth_pipe.run(&config).context("auth process")?;

Prevention

When it happens

Trigger: First call to `LazyPipe::run(config)` where `spawn_auth(config)` fails (auth executable not found, not executable, bad args). The error is stored in the `RefCell<Option<Result<...>>>`, so all later runs bail with `e.to_string()` — the original spawn error.

Common situations: Auth helper not built/installed before running; misconfigured path in Config; environment lacking PATH or permissions to execute the helper; after a package upgrade the binary moved.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of Morganamilo/paru@9ac3578807 (2026-09-12). Data as JSON: /api/errors/08e33b7b90cebc01. Report an issue: GitHub.

Appendix: source

Thrown at src/auth.rs:35

    fn wait_ok(&mut self) -> Result<()> {
        let mut buf = [0; "ok\n".len()];
        self.read.read_exact(&mut buf)?;
        ensure!(&buf == b"ok\n");
        Ok(())
    }
}

#[derive(Debug, Default)]
pub struct LazyPipe {
    pipe: RefCell<Option<Result<Pipe>>>,
}

impl LazyPipe {
    pub fn run(&self, config: &Config) -> Result<()> {
        let mut pipe = self.pipe.borrow_mut();
        let pipe = pipe.get_or_insert_with(|| spawn_auth(config).context("failed to spawn auth process"));
        let pipe = match pipe {
            Err(e) => bail!(e.to_string()),
            Ok(p) => p,
        };
        loop {}
        pipe.write.write_all(b"something")?;
        pipe.wait_ok()?;
        Ok(())
    }
}

pub fn spawn_auth(config: &Config) -> Result<Pipe> {
    let (paru_read, auth_write) = pipe()?;
    let (auth_read, paru_write) = pipe()?;


    /*Command::new(&config.sudo_bin)
        .args(&config.sudo_flags)
        .arg(std::env::current_exe()?)
        .arg("--authpipe")

View on GitHub (pinned to 9ac3578807)