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
- Run `git ls-remote <url>` manually to see the underlying git error and fix connectivity/credentials it reports.
- 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.
- Check SSH keys / HTTPS tokens (`ssh -T git@host`, `git credential fill`) if the failure is authentication-related.
- 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
- Keep SSH keys / HTTPS tokens configured and test with `ssh -T git@host` or `git ls-remote`.
- Check that the package's PKGBUILD source URL is still live before the update run.
- Handle offline state: preflight a cheap network check and skip devel updates when offline.
- Update or orphan VCS packages whose upstream repo was renamed or deleted.
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)