{"record":{"id":"6b3664f2939b52ba","repo":"denoland/deno","slug":"failed-to-move-extracted-package-into-e-ini","errorCode":null,"errorMessage":"Failed to move extracted package into {}: {e} (initial: {rename_err})","messagePattern":"Failed to move extracted package into (.+?): (.+?) \\(initial: (.+?)\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/tools/installer/npm_compat.rs","lineNumber":1120,"sourceCode":"        // Another process published a complete copy first. Its tree is as good\n        // as ours, so keep it and drop the staging dir.\n        let _ = std::fs::remove_dir_all(&tmp_dir);\n        return Ok(());\n      }\n      // `dest` is stale: half-extracted by a killed process, or written\n      // non-atomically by an older Deno. Clearing it is what heals a cache that\n      // is already poisoned - otherwise every later run skips the download and\n      // keeps type checking against an incomplete tree.\n      let _ = std::fs::remove_dir_all(dest);\n      match std::fs::rename(&tmp_dir, dest) {\n        Ok(()) => Ok(()),\n        Err(e) => {\n          let _ = std::fs::remove_dir_all(&tmp_dir);\n          // A third process may have published `dest` in between.\n          if is_materialized_package(dest) {\n            return Ok(());\n          }\n          Err(anyhow!(\n            \"Failed to move extracted package into {}: {e} (initial: {rename_err})\",\n            dest.display()\n          ))\n        }\n      }\n    }\n  }\n}\n\n/// Extract a gzipped npm-style tarball into `dest`, stripping the leading\n/// `package/` directory the way `tar --strip-components=1` does. Replaces\n/// the previous `tar` shell-out so the install works the same on Linux,\n/// macOS (BSD tar), Windows, and minimal containers without `tar`/`curl`.\nfn extract_tarball_gz(gz_bytes: &[u8], dest: &Path) -> Result<(), AnyError> {\n  std::fs::create_dir_all(dest)?;\n  let mut archive = tar::Archive::new(GzDecoder::new(gz_bytes));\n  for entry in archive.entries()? {\n    let mut entry = entry?;","sourceCodeStart":1102,"sourceCodeEnd":1138,"githubUrl":"https://github.com/denoland/deno/blob/336da420f4343cbb1dcbd5eed9d075ff555ed6ee/cli/tools/installer/npm_compat.rs#L1102-L1138","documentation":"extract_tarball_gz_atomic stages the extraction into a sibling temp dir and then renames it into place. If that final rename fails, the code cleans up the staging dir and re-checks whether another concurrent process already published dest (is_materialized_package); only if not does it throw this error containing both the rename failure and the initial error, indicating the package could not be atomically installed at dest.","triggerScenarios":"The std::fs::rename of the staging dir into dest fails (dest locked/AV-scanned on Windows, cross-device rename despite sibling staging, permission denied, dest recreated in a conflicting state by a racing process between the rename attempt and the recheck).","commonSituations":"Parallel deno installs racing on the same npm cache entry; antivirus/indexer holding the target dir open on Windows; read-only or full cache filesystem; permission changes on the cache directory.","solutions":["Re-run the install command — the failure is often transient (lock held by another process or AV scan).","Clear the corrupted target directory in the npm cache (remove dest) and retry so extraction starts fresh.","Check permissions and free space on the cache parent directory.","Reduce concurrency (avoid running multiple deno installs against the same DENO_DIR simultaneously) or exclude the cache dir from antivirus scanning."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust\nmatch extract_tarball_gz_atomic(&gz, &dest) {\n  Ok(()) => {},\n  Err(e) if e.to_string().contains(\"Failed to move extracted package\") => {\n    std::thread::sleep(std::time::Duration::from_millis(250));\n    std::fs::remove_dir_all(&dest).ok(); // clear partial/conflicting target, then retry\n    extract_tarball_gz_atomic(&gz, &dest)?;\n  }\n  Err(e) => return Err(e),\n}","preventionTips":["Avoid concurrent installs sharing the same DENO_DIR/npm cache.","Exclude the cache directory from antivirus real-time scanning on Windows.","Ensure cache directory permissions and free space before installing.","On failure, delete the partially materialized dest and retry once."],"tags":["filesystem","concurrency","npm","rename"],"backgroundTag":"file-write-failed","analyzedSha":"336da420f4343cbb1dcbd5eed9d075ff555ed6ee","analyzedAt":"2026-09-11T17:12:50.272Z","contentChangedAt":"2026-09-11T17:12:50.272Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}