windmill-labs/windmill · error
Unexpected output format for git ls-remote
Error message
Unexpected output format for git ls-remote
What it means
Windmill expects `git ls-remote <url> HEAD` to print exactly one line (`<hash>\trefs/heads/HEAD` style). If stdout has any other number of lines, the output format is considered unexpected and the locking step fails rather than guessing a commit.
Source
Thrown at backend/windmill-worker/src/ansible_executor.rs:1181
let mut git_cmd = Command::new(GIT_PATH.as_str());
git_cmd
.env("GIT_SSH_COMMAND", git_ssh_cmd)
.args(["ls-remote", &repo.url, "HEAD"]);
let output = git_cmd.stderr(Stdio::piped()).output().await?;
if !output.status.success() {
let stderr = String::from_utf8(output.stderr)?;
return Err(anyhow!("Error getting git repo commit hash: {stderr}"));
}
let stdout = String::from_utf8(output.stdout)?;
let lines: Vec<&str> = stdout.lines().collect();
if lines.len() != 1 {
return Err(anyhow!("Unexpected output format for git ls-remote",));
}
Ok(lines
.first()
.ok_or(anyhow!(
"The HEAD commit hash was not found for repo `{}`",
sanitize_git_url(&repo.url)
))?
.split_whitespace()
.next()
.map(|s| s.to_string())
.ok_or(anyhow!("Unexpected output format for git ls-remote"))?)
}
pub async fn get_git_repos_lock(
repos: &Vec<GitRepo>,
job_dir: &str,
job_id: &Uuid,View on GitHub (pinned to e474e8803c)
Solutions
- Run `git ls-remote <url> HEAD` manually and inspect the raw line count.
- Remove any git URL rewriting (insteadOf/rewrite rules, wrapper scripts) that injects extra output.
- Ensure the remote repository actually exists and has a resolvable HEAD.
- Pin a commit in the job's git-repo dependency to avoid relying on HEAD resolution.
Defensive patterns
Strategy: validation
Validate before calling
out=$(git ls-remote "$REPO_URL" HEAD) [ "$(printf '%s\n' "$out" | wc -l)" -eq 1 ] && echo OK || echo 'unexpected ls-remote line count'
Try / catch
match get_git_repo_full_head_commit_hash(&repo, ...).await {
Ok(h) => h,
Err(e) => { log::warn!("HEAD resolution failed: {e}"); fallback_to_pinned_commit() }
} Prevention
- Avoid insteadOf/wrapper scripts that rewrite git URLs on workers
- Pin explicit commits in job dependencies to skip HEAD resolution
- Ensure the remote is a standard git server
When it happens
Trigger: The ls-remote invocation returns zero lines (empty but successful output) or multiple lines — e.g. an unusual remote wrapper/alias outputting extra text, or a URL that resolves to something that is not a normal git remote.
Common situations: A git URL rewrite/insteadOf wrapper adding output; a smart-HTTP endpoint returning a banner; empty repo where HEAD cannot be resolved but git still exits 0.
Related errors
- The HEAD commit hash was not found for repo `{}`
- You can only create forks within a git repo. Forks are track
- Could not get git branch name
- --from-branch is for converting a *different* working branch
- Refusing to rename your current branch \`${currentBranch}\`
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/b65079bae33c9792.
Report an issue: GitHub.