{"record":{"id":"9aa30b97a3ac4af2","repo":"Hmbown/CodeWhale","slug":"failed-to-extract-ops-origin-main-archive","errorCode":null,"errorMessage":"failed to extract ops origin/main archive","messagePattern":"failed to extract ops origin/main archive","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/operate.rs","lineNumber":913,"sourceCode":"            String::from_utf8_lossy(&archive.stderr).trim()\n        );\n    }\n    let mut child = Command::new(\"tar\")\n        .arg(\"-x\")\n        .arg(\"-C\")\n        .arg(&dest)\n        .stdin(Stdio::piped())\n        .stdout(Stdio::null())\n        .stderr(Stdio::piped())\n        .spawn()\n        .context(\"tar extract ops origin/main\")?;\n    if let Some(mut stdin) = child.stdin.take() {\n        use std::io::Write;\n        stdin.write_all(&archive.stdout)?;\n    }\n    let status = child.wait()?;\n    if !status.success() {\n        anyhow::bail!(\"failed to extract ops origin/main archive\");\n    }\n    if !marker.is_file() {\n        anyhow::bail!(\"ops origin/main archive missing {CHECK_AUTO_MERGE_SCRIPT}\");\n    }\n    Ok(dest)\n}\n\npub fn default_operate_dir() -> PathBuf {\n    if let Ok(path) = std::env::var(\"CODEWHALE_OPERATE_DIR\") {\n        let trimmed = path.trim();\n        if !trimmed.is_empty() {\n            return PathBuf::from(trimmed);\n        }\n    }\n    crate::automation_manager::default_automations_dir()\n        .parent()\n        .map(|parent| parent.join(\"operate\"))\n        .unwrap_or_else(|| PathBuf::from(\"operate\"))","sourceCodeStart":895,"sourceCodeEnd":931,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/operate.rs#L895-L931","documentation":"After piping the `git archive` output into `tar -x`, materialize_ops_origin_main checks tar's exit status. A non-zero status from tar means the ops archive could not be extracted to the destination directory, so the ops tree is not available.","triggerScenarios":"tar exits non-zero while extracting the archive: destination directory not writable, disk full, tar incompatible with the stream, or truncated/corrupt archive stdout.","commonSituations":"Read-only or missing destination directory; tar/gnu-tar version differences; interrupted pipe between git archive and tar; insufficient disk space.","solutions":["Check the destination directory exists and is writable (permissions, disk space)","Re-run after a successful `git fetch origin main` to get a fresh archive","Run `git archive origin/main | tar -t` manually to see tar's diagnostic","Ensure a compatible `tar` binary is on PATH"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let dest_ok = dest.exists() && dest.permissions().ok().map(|p| !p.readonly()).unwrap_or(false);","typeGuard":null,"tryCatchPattern":"match materialize_ops_origin_main(dest) { Err(e) if e.to_string().contains(\"failed to extract\") => { fs_err::remove_dir_all(dest).ok(); fs_err::create_dir_all(dest)?; retry_once(materialize_ops_origin_main, dest)?; } other => other?, }","preventionTips":["Ensure the destination is empty, writable, and on a volume with free space","Verify `tar` is installed and on PATH","Clean partial extraction directories before retrying"],"tags":["tar","extraction","subprocess"],"backgroundTag":"file-write-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}