denoland/deno · error

failed to atomic-rename LAUFEY cache to

Error message

failed to atomic-rename LAUFEY cache to {}: {e}

What it means

The downloaded archive is extracted into a sibling staging tempdir and then moved into place with fs::rename(staging, dir) so concurrent `deno desktop` runs never observe a half-populated cache. If the rename fails, the code first checks whether a concurrent process won the race (success marker exists) and only then errors. This message therefore means the rename failed for a non-race reason: permissions, an unexpected existing directory, or something holding locks on the target path.

Solutions

  1. Delete the laufey cache directory named in the error and re-run — this clears stale locks and corrupt leftovers.
  2. Check write permissions on the cache root (ls -ld on the parent, or icacls on Windows) and fix ownership.
  3. On Windows, temporarily exclude the deno cache dir from real-time antivirus scanning, or just re-run after a few seconds once the scanner releases the handle.
  4. Ensure no other `deno desktop` process is mid-download to the same cache (check with tman list / ps).

Example fix

# before
deno desktop
# error: failed to atomic-rename LAUFEY cache to /home/me/.cache/deno/desktop/laufey/...

# after: clear the stuck target and retry
rm -rf /home/me/.cache/deno/desktop/laufey/v1.2.3-aarch64-apple-darwin
deno desktop
Defensive patterns

Strategy: retry

Validate before calling

# Make sure the target cache dir is removable/writable before the run
cache_dir="$HOME/.cache/deno/desktop/laufey/$VER-$TARGET"
rm -rf "$cache_dir" 2>/dev/null
touch "$(dirname "$cache_dir")/.write-probe" && rm -f "$(dirname "$cache_dir")/.write-probe"

Try / catch

Catch the 'failed to atomic-rename' error, delete the target cache dir named in the message, and retry once after a short pause (Windows AV locks usually release within seconds); if it fails identically twice, stop and report a permissions problem rather than looping.

Prevention

When it happens

Trigger: fs::rename of the staged cache dir fails while no concurrent process's success marker exists at the target: the cache dir exists and is locked (Windows antivirus/indexer), the user lacks write permission on the cache root, a stale half-deleted directory survived the remove_dir_all above, or the filesystem refuses the rename.

Common situations: Windows Defender or a search indexer briefly locks the freshly created cache directory; a previous run was killed mid-extract leaving a corrupt dir; the cache lives on a filesystem mounted read-only or with restrictive permissions; two runs raced and one left no marker because it also failed.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/20435a567fcec98b. Report an issue: GitHub.

Appendix: source

Thrown at cli/tools/desktop.rs:2049

    if marker.exists() {
      return Ok(dir);
    }

    // Discard any prior failed-extract debris (no marker ⇒ partial).
    // `rename` refuses a non-empty target.
    if dir.exists() {
      std::fs::remove_dir_all(&dir)?;
    }

    let staging_path = staging.into_path();
    if let Err(e) = std::fs::rename(&staging_path, &dir) {
      // Lost a rename race with a concurrent process — its dir is at
      // our target path now. Drop our staged copy and use theirs.
      let _ = std::fs::remove_dir_all(&staging_path);
      if marker.exists() {
        return Ok(dir);
      }
      return Err(deno_core::anyhow::anyhow!(
        "failed to atomic-rename LAUFEY cache to {}: {e}",
        dir.display(),
      ));
    }

    // The laufey release archive linker-signs the `laufey` binary with
    // identifier=`laufey` rather than the .app's CFBundleIdentifier. UN
    // (UNUserNotificationCenter) rejects authorization requests when
    // the running binary's signed identifier disagrees with the host
    // bundle's id (UNErrorCodeNotificationsNotAllowed, error code 1).
    // In HMR mode the user's project bundle isn't involved — we run
    // laufey.app directly — so we have to fix the cached copy itself.
    // Re-sign every Mach-O inside the cached laufey.app with the bundle
    // id so the running identity is internally consistent. No-op on
    // non-macOS targets / hosts (no `codesign(1)`).
    #[cfg(target_os = "macos")]
    if target.contains("apple-darwin")
      && let Err(e) = harmonize_cached_laufey_identifiers(&dir, backend)

View on GitHub (pinned to f7822238ca)