{"record":{"id":"b65079bae33c9792","repo":"windmill-labs/windmill","slug":"unexpected-output-format-for-git-ls-remote","errorCode":null,"errorMessage":"Unexpected output format for git ls-remote","messagePattern":"Unexpected output format for git ls-remote","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-worker/src/ansible_executor.rs","lineNumber":1181,"sourceCode":"    let mut git_cmd = Command::new(GIT_PATH.as_str());\n\n    git_cmd\n        .env(\"GIT_SSH_COMMAND\", git_ssh_cmd)\n        .args([\"ls-remote\", &repo.url, \"HEAD\"]);\n\n    let output = git_cmd.stderr(Stdio::piped()).output().await?;\n\n    if !output.status.success() {\n        let stderr = String::from_utf8(output.stderr)?;\n        return Err(anyhow!(\"Error getting git repo commit hash: {stderr}\"));\n    }\n\n    let stdout = String::from_utf8(output.stdout)?;\n\n    let lines: Vec<&str> = stdout.lines().collect();\n\n    if lines.len() != 1 {\n        return Err(anyhow!(\"Unexpected output format for git ls-remote\",));\n    }\n\n    Ok(lines\n        .first()\n        .ok_or(anyhow!(\n            \"The HEAD commit hash was not found for repo `{}`\",\n            sanitize_git_url(&repo.url)\n        ))?\n        .split_whitespace()\n        .next()\n        .map(|s| s.to_string())\n        .ok_or(anyhow!(\"Unexpected output format for git ls-remote\"))?)\n}\n\npub async fn get_git_repos_lock(\n    repos: &Vec<GitRepo>,\n    job_dir: &str,\n    job_id: &Uuid,","sourceCodeStart":1163,"sourceCodeEnd":1199,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-worker/src/ansible_executor.rs#L1163-L1199","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"out=$(git ls-remote \"$REPO_URL\" HEAD)\n[ \"$(printf '%s\\n' \"$out\" | wc -l)\" -eq 1 ] && echo OK || echo 'unexpected ls-remote line count'","typeGuard":null,"tryCatchPattern":"match get_git_repo_full_head_commit_hash(&repo, ...).await {\n    Ok(h) => h,\n    Err(e) => { log::warn!(\"HEAD resolution failed: {e}\"); fallback_to_pinned_commit() }\n}","preventionTips":["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"],"tags":["git","output-parsing"],"backgroundTag":"unexpected-command-output-format","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}