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

  1. Run `git ls-remote <url> HEAD` manually and inspect the raw line count.
  2. Remove any git URL rewriting (insteadOf/rewrite rules, wrapper scripts) that injects extra output.
  3. Ensure the remote repository actually exists and has a resolvable HEAD.
  4. 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

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


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/b65079bae33c9792. Report an issue: GitHub.