jdx/mise · error
run `mise dot save ` first: --keep-local publishes this…
Error message
run `mise dot save {path}` first: --keep-local publishes this machine's saved version of {path}, and it {reason} What it means
`mise dot pull --keep-local <path>` resolves a sync conflict by publishing the version of the file that was previously *saved* on this machine. This error is thrown when the live file cannot serve that purpose: either the machine has no saved baseline for the path at all (freshly enrolled) or the file has unsaved edits since the last `mise dot save`. The command refuses rather than silently publishing a stale or nonexistent version.
Solutions
- Run `mise dot save <path>` to record the current local content as the machine's baseline, then retry `mise dot pull --keep-local <path>`.
- If the edits are unwanted, restore the file to its saved version or run `mise dot pull --take-remote <path>` instead of --keep-local.
- Check `mise dot status` to see which paths have unsaved changes before choosing a resolution.
Example fix
before: mise dot pull --keep-local ~/.bashrc (fails: unsaved changes) | after: mise dot save ~/.bashrc && mise dot pull --keep-local ~/.bashrc
Defensive patterns
Strategy: validation
Validate before calling
mise dot status | grep -F '<path>' # confirm no 'unsaved changes' entry before --keep-local
Prevention
- Run `mise dot save` after every intentional edit to a shared dotfile.
- Check `mise dot status` before pulling with resolution flags.
- On a newly enrolled machine, complete the initial save/setup before using --keep-local.
When it happens
Trigger: Running `mise dot pull --keep-local <path>` (explicitly or via a blanket keep-local choice) when the live object or mode differs from the saved baseline in the shared snapshot: (1) no saved version exists yet for the path, (2) the live file on disk differs from the saved baseline in content or permissions.
Common situations: A freshly enrolled machine trying to keep local before ever saving; editing a shared dotfile after the last `mise dot save` and then pulling with --keep-local; file permissions changed since the save.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- incoming setup has not been completely applied; run `mise…
- is an existing repository without the mise marker; `mise…
- no setup repository is connected; `mise bootstrap dotfiles…
- save before choosing --keep-local
- sync paused: resolve all
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/998f5d818afb2c6e.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/sync/apply.rs:255
let reason = if saved.is_none() {
"has no saved version on this machine yet"
} else {
"has unsaved changes"
};
// The refusal stands either way, but as with an unusable live
// side a blanket choice holds just this path rather than
// discarding every decision it made alongside it. A path named
// on the command line is the user's own instruction, so it
// still fails the pass.
if blanket_chosen.contains(&local) {
blanket_held.push(format!(
"{path} {reason}, so run `mise dot save {path}` first",
path = display_path(&local)
));
keep_local.remove(&local);
continue;
}
bail!(
"run `mise dot save {path}` first: --keep-local publishes this machine's saved version of {path}, and it {reason}",
path = display_path(&local)
);
}
let remote = match status.upstream_commit.as_deref() {
Some(head) => repo
.object_at(head, &conflict.branch_path)?
.map(|object| {
if !encrypted.contains(&conflict.branch_path) {
return Ok(object);
}
super::files::decrypt(
repo,
&conflict.branch_path,
&object,
!req.automatic && console::user_attended_stderr(),
)
})View on GitHub (pinned to 533346cc37)