{"record":{"id":"173a52437f7c2574","repo":"jdx/mise","slug":"failed-rename-err","errorCode":null,"errorMessage":"failed rename: {} -> {}: {err}","messagePattern":"failed rename: (.+?) -> (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/add.rs","lineNumber":348,"sourceCode":"                                    )\n                                })?;\n                                let recovery = tempfile::Builder::new()\n                                    .prefix(\".mise-dotfiles-rollback-\")\n                                    .tempdir_in(parent)?;\n                                let recovery_path = recovery.path().join(\"target\");\n                                // Keep the original on its own filesystem until\n                                // the entire transaction succeeds. This makes\n                                // rollback an atomic rename instead of another\n                                // potentially failing recursive removal.\n                                file::rename(&item.target, &recovery_path)?;\n                                moved_targets.push(MovedTarget {\n                                    target: item.target.clone(),\n                                    source: item.source.clone(),\n                                    recovery: Some(recovery),\n                                });\n                                system::files::copy_path(&recovery_path, &item.source)?;\n                            }\n                            Err(err) => bail!(\n                                \"failed rename: {} -> {}: {err}\",\n                                item.target.display_user(),\n                                item.source.display_user()\n                            ),\n                        }\n                        journal::commit_changes(pending);\n                        info!(\n                            \"dotfiles: moved {} to {}\",\n                            item.target.display_user(),\n                            item.source.display_user()\n                        );\n                    } else {\n                        target_backups.push((\n                            item.target.clone(),\n                            backup_path(\n                                &item.target,\n                                &backup_dir.path().join(\"targets\").join(index.to_string()),\n                            )?,","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/dotfiles/add.rs#L330-L366","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check and fix permissions on both the target file and the destination source directory.","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.","Re-run the add; the journal/recovery data recorded before the failure lets the operation recover the file."],"exampleFix":"# before\nmise bootstrap dotfiles add ~/.zshrc --source /mnt/otherfs/dotfiles/zshrc  # cross-device rename fails\n# after\nmise bootstrap dotfiles add ~/.zshrc --source ~/dotfiles/zshrc  # same filesystem","handlingStrategy":"validation","validationCode":"// ensure source and target are on the same device before add\nimport { statfsSync } from 'node:fs';\nfunction sameDevice(a, b) {\n  return statfsSync(a).dev === statfsSync(b).dev;\n}","typeGuard":null,"tryCatchPattern":"try {\n  execSync(`mise bootstrap dotfiles add ${target} --source ${source}`);\n} catch (e) {\n  if (String(e.stderr).includes('failed rename')) {\n    console.error('Check permissions/destination existence; journal has recovery info.');\n  } else throw e;\n}","preventionTips":["Keep dotfile sources on the same filesystem as the targets to avoid EXDEV rename errors.","Ensure the source directory exists and is writable before running add.","Don't delete the recovery/backup data mentioned in failures — it enables recovery."],"tags":["filesystem","dotfiles","rename","io-error"],"backgroundTag":"file-write-failed","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}