Morganamilo/paru · error

{}

Error message

{}

What it means

In src/devel.rs:275 (ls_remote_internal), the crate shells out to `git ls-remote <remote> <branch|HEAD>` to resolve a VCS package's latest commit. If git exits non-zero, the raw stderr text is propagated as the error via `bail!("{}", ...)`. The message is exactly git's own output (e.g. "fatal: could not read from remote repository"), so the thrown message content varies with what git printed.

Solutions

  1. Run `git ls-remote <url>` manually to see the underlying git error and fix connectivity/credentials it reports.
  2. Verify the package's source URL in its PKGBUILD still points to a live repository and branch; update the package or its URL if upstream moved.
  3. Check SSH keys / HTTPS tokens (`ssh -T git@host`, `git credential fill`) if the failure is authentication-related.
  4. If the VCS package is abandoned, remove it or switch to a maintained fork's package.
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe reachability/credentials before the update sweep
let ok = std::process::Command::new("git")
    .args(["ls-remote", "--exit-code", remote])
    .output()
    .map(|o| o.status.success())
    .unwrap_or(false);
if !ok { eprintln!("skipping {remote}: unreachable"); }

Try / catch

match ls_remote(&pkg).await {
    Ok(info) => use(info),
    Err(e) => {
        // stderr from git ls-remote is embedded in the message
        eprintln!("devel check failed for {}: {e}", pkg.name);
        eprintln!("hint: run `git ls-remote <url>` to see the raw git error");
        // continue with remaining packages instead of aborting the sweep
    }
}

Prevention

When it happens

Trigger: Any non-zero exit of `git ls-remote` during devel (VCS) package update checks: the remote URL is unreachable, the repository was deleted or renamed, the branch/ref no longer exists, SSH keys/passphrases are missing, or network/DNS fails.

Common situations: Checking AUR -git/-svn/-hg packages after upstream repo moved to a different host; offline or behind a proxy/firewall; SSH deploy key not configured for a private repo; branch renamed upstream so `HEAD`/branch arg fails.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


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

Appendix: source

Thrown at src/devel.rs:275

    branch: Option<&str>,
) -> Result<String> {
    #[cfg(feature = "mock")]
    let _ = git;
    #[cfg(feature = "mock")]
    let git = "git";

    let mut command = AsyncCommand::new(git);
    command
        .args(flags)
        .env("GIT_TERMINAL_PROMPT", "0")
        .arg("ls-remote")
        .arg(remote)
        .arg(branch.unwrap_or("HEAD"));

    debug!("git ls-remote {} {}", remote, branch.unwrap_or("HEAD"));
    let output = command.output().await?;
    if !output.status.success() {
        bail!("{}", String::from_utf8_lossy(&output.stderr));
    }

    let sha = String::from_utf8_lossy(&output.stdout)
        .split('\t')
        .next()
        .unwrap()
        .to_string();

    Ok(sha)
}

async fn ls_remote(
    style: Style,
    git: &str,
    flags: &[String],
    remote: String,
    branch: Option<&str>,
) -> Result<String> {

View on GitHub (pinned to 9ac3578807)