{"record":{"id":"50c5aae881a81434","repo":"windmill-labs/windmill","slug":"failed-to-extract-repository-archive-e","errorCode":null,"errorMessage":"Failed to extract repository archive: {e}","messagePattern":"Failed to extract repository archive: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-worker/src/ansible_executor.rs","lineNumber":499,"sourceCode":"        let mut stream = response.bytes_stream();\n        while let Some(chunk) = stream.next().await {\n            let chunk = chunk.map_err(|e| anyhow!(\"Failed to read repository archive: {e}\"))?;\n            file.write_all(&chunk).await?;\n        }\n        file.flush().await?;\n        drop(file);\n\n        // Dropping the join handle detaches the blocking task rather than\n        // stopping it, so the flag is what a cancelled job uses to reach the\n        // extraction loop. The guard sets it when this future is dropped.\n        let aborted = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));\n        let _abort_on_drop = AbortOnDrop(aborted.clone());\n        let unpack_archive = download_archive.clone();\n        tokio::task::spawn_blocking(move || {\n            unpack_repo_archive(&unpack_archive, &download_target, &aborted)\n        })\n        .await\n        .map_err(|e| anyhow!(\"Failed to extract repository archive: {e}\"))??;\n\n        Ok(commit)\n    };\n\n    // Through the job poller, like the git clone paths: the download has no\n    // wall-clock bound of its own, so this is what makes a cancelled or\n    // timed-out run stop occupying the worker.\n    let commit = run_future_with_polling_update_job_poller(\n        job.id,\n        job.timeout,\n        conn,\n        mem_peak,\n        canceled_by,\n        fetch,\n        worker_name,\n        &job.workspace_id,\n        &mut Some(occupancy_metrics),\n        Box::pin(futures::stream::once(async { 0 })),","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-worker/src/ansible_executor.rs#L481-L517","documentation":"The blocking task that unpacks the downloaded repository archive failed, or the tokio task itself panicked/was cancelled — the JoinError is wrapped with this message. The double `??` means both JoinError and the inner unpack error surface.","triggerScenarios":"fetch_repo_archive spawns unpack_repo_archive via spawn_blocking; the archive is corrupt/truncated (e.g. from error 1008's download), the disk is full, or the blocking task panicked.","commonSituations":"Partial archive saved from an interrupted download; insufficient disk space in the worker; unsupported archive format; abort signal triggering early exit.","solutions":["Check the inner error after this message for the actual unpack failure","Delete and re-download the archive (a truncated file from a failed download is the usual cause)","Verify free disk space at download_target","Confirm the archive format is supported by unpack_repo_archive (tar/zip as expected)"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"# before extracting\ntar -tzf \"$ARCHIVE\" >/dev/null 2>&1 || echo \"archive corrupt/truncated\"\ndf -h \"$(dirname \"$DOWNLOAD_TARGET\")\" | tail -n1  # disk space","typeGuard":null,"tryCatchPattern":"match fetch_repo_archive(...).await {\n    Err(e) if e.to_string().contains(\"Failed to extract repository archive\") => {\n        eprintln!(\"delete archive and re-download: {e:#}\");\n        // fallback: re-fetch then retry once\n    }\n    other => other?,\n}","preventionTips":["Verify archive integrity after download before unpacking","Monitor worker disk space","Re-download rather than reuse archives from interrupted runs","Keep the abort/cancellation signal consistent between download and unpack phases"],"tags":["rust","archive","extraction","tokio"],"backgroundTag":"archive-extraction-failed","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"}