windmill-labs/windmill · error
Failed to read repository archive: {e}
Error message
Failed to read repository archive: {e} What it means
While streaming a repository archive download to disk chunk by chunk, one HTTP chunk failed to arrive (reqwest error wrapped in anyhow). The download is aborted so a partial archive is never extracted.
Source
Thrown at backend/windmill-worker/src/ansible_executor.rs:483
return Err(error::Error::BadRequest(format!(
"Failed to download `{}` ({}): {}",
resource, status, body
)));
}
let commit = response
.headers()
.get("x-commit-sha")
.and_then(|v| v.to_str().ok())
.unwrap_or("unknown")
.to_string();
// Written out chunk by chunk: a repository is arbitrarily large, and
// holding one in the worker's memory would take every job on it down.
let mut file = tokio::fs::File::create(&download_archive).await?;
let mut stream = response.bytes_stream();
while let Some(chunk) = stream.next().await {
let chunk = chunk.map_err(|e| anyhow!("Failed to read repository archive: {e}"))?;
file.write_all(&chunk).await?;
}
file.flush().await?;
drop(file);
// Dropping the join handle detaches the blocking task rather than
// stopping it, so the flag is what a cancelled job uses to reach the
// extraction loop. The guard sets it when this future is dropped.
let aborted = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let _abort_on_drop = AbortOnDrop(aborted.clone());
let unpack_archive = download_archive.clone();
tokio::task::spawn_blocking(move || {
unpack_repo_archive(&unpack_archive, &download_target, &aborted)
})
.await
.map_err(|e| anyhow!("Failed to extract repository archive: {e}"))??;
Ok(commit)View on GitHub (pinned to e474e8803c)
Solutions
- Retry the job — the code deletes partial state on failure
- Check network stability/proxy timeouts between worker and the git host
- Reduce archive size (shallow/subset repos) if the host truncates large transfers
- Verify the archive URL is still valid and the token hasn't expired mid-transfer
Defensive patterns
Strategy: retry
Validate before calling
curl -sSI "$ARCHIVE_URL" | head -n1 # check reachability before streaming df -h "$DOWNLOAD_DIR" # ensure disk space
Try / catch
let mut attempts = 0;
loop {
match fetch_repo_archive(...).await {
Err(e) if e.to_string().contains("Failed to read repository archive") && attempts < 2 => {
attempts += 1;
tokio::time::sleep(Duration::from_secs(5 * attempts)).await;
}
other => { other?; break; }
}
} Prevention
- Retry large downloads; keep per-chunk failure handling
- Check proxy/idle-timeout settings for long transfers
- Monitor worker network stability to the git host
- Ensure archive URL tokens are valid for the whole transfer
When it happens
Trigger: Network interruption, proxy timeout, or the git/archive server closing the connection mid-stream while the worker streams response.bytes_stream().
Common situations: Large repos over flaky networks; corporate proxies with short idle timeouts; git host rate-limiting or resetting connections.
Related errors
- No response body for SSE stream
- Failed to download esbuild-wasm@${version} (${res.status} ${
- Error streaming get request from authed http client to {url}
- Error requesting oidc token from {url}: {e:#?}
- HTTP agent request POST {} failed {}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/5c237fa25da03ab3.
Report an issue: GitHub.