jdx/mise · error

failed rename: {} -> {}: {err}

Error message

failed rename: {} -> {}: {err}

What it means

During the add flow's --source-seeding rename (moving the target file to become the managed source), a filesystem error on the rename operation is surfaced as `failed rename: <target> -> <source>: <err>`. The code copies a recovery path back to the source before this, but if the actual rename(2)/move of target to source fails, the run aborts so the journal can be committed with recovery info rather than leaving silent partial state.

Source

Thrown at src/cli/dotfiles/add.rs:348

                                    )
                                })?;
                                let recovery = tempfile::Builder::new()
                                    .prefix(".mise-dotfiles-rollback-")
                                    .tempdir_in(parent)?;
                                let recovery_path = recovery.path().join("target");
                                // Keep the original on its own filesystem until
                                // the entire transaction succeeds. This makes
                                // rollback an atomic rename instead of another
                                // potentially failing recursive removal.
                                file::rename(&item.target, &recovery_path)?;
                                moved_targets.push(MovedTarget {
                                    target: item.target.clone(),
                                    source: item.source.clone(),
                                    recovery: Some(recovery),
                                });
                                system::files::copy_path(&recovery_path, &item.source)?;
                            }
                            Err(err) => bail!(
                                "failed rename: {} -> {}: {err}",
                                item.target.display_user(),
                                item.source.display_user()
                            ),
                        }
                        journal::commit_changes(pending);
                        info!(
                            "dotfiles: moved {} to {}",
                            item.target.display_user(),
                            item.source.display_user()
                        );
                    } else {
                        target_backups.push((
                            item.target.clone(),
                            backup_path(
                                &item.target,
                                &backup_dir.path().join("targets").join(index.to_string()),
                            )?,

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Check and fix permissions on both the target file and the destination source directory.
  2. Choose a --source location on the same filesystem/mount as the target to avoid EXDEV, or free space / remove an existing file at the destination.
  3. Re-run the add; the journal/recovery data recorded before the failure lets the operation recover the file.

Example fix

# before
mise bootstrap dotfiles add ~/.zshrc --source /mnt/otherfs/dotfiles/zshrc  # cross-device rename fails
# after
mise bootstrap dotfiles add ~/.zshrc --source ~/dotfiles/zshrc  # same filesystem
Defensive patterns

Strategy: validation

Validate before calling

// ensure source and target are on the same device before add
import { statfsSync } from 'node:fs';
function sameDevice(a, b) {
  return statfsSync(a).dev === statfsSync(b).dev;
}

Try / catch

try {
  execSync(`mise bootstrap dotfiles add ${target} --source ${source}`);
} catch (e) {
  if (String(e.stderr).includes('failed rename')) {
    console.error('Check permissions/destination existence; journal has recovery info.');
  } else throw e;
}

Prevention

When it happens

Trigger: Rename/move of item.target to item.source fails during the source-seeding step — e.g. source is on a different filesystem/mount (EXDEV), destination exists, permissions denied on either path, or the target vanished mid-operation.

Common situations: Source directory on a different mount point than the dotfile target (cross-device link errors); read-only source dir; target file held open/locked on some filesystems; disk full.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/173a52437f7c2574. Report an issue: GitHub.