jdx/mise · error
{}
Error message
{} What it means
When `mise lock` finishes (or rolls back), it restores snapshotted lockfile contents; any per-file restore failures are collected and joined into a single error via `bail!("{}", errors.join("\n"))`. This error surfaces one or more underlying restore failures (I/O, permissions, missing files) that prevented returning the filesystem to its pre-command state.
Solutions
- Read the joined messages to identify which files failed to restore
- Fix permissions on the listed lockfiles (chmod/chown) and re-run the command
- Check disk space and that the lockfiles still exist; restore from git if contents were lost (`git checkout -- mise.lock`)
Example fix
// before chmod 444 mise.lock // after chmod 644 mise.lock mise lock
Defensive patterns
Strategy: try-catch
Validate before calling
// bash: ensure lockfiles are writable before locking for f in mise.lock; do [[ -w "$f" ]] || chmod u+w "$f"; done
Try / catch
// bash if ! mise lock; then git checkout -- mise.lock; mise lock; fi
Prevention
- Keep lockfiles writable by the user running mise
- Ensure adequate disk space
- Don't delete lockfiles while mise commands run
When it happens
Trigger: `restore_lockfile_snapshots` fails to write back original lockfile content for one or more paths — e.g. read-only filesystem, file deleted by another process, permission change — during normal completion or rollback (as in the rollback tests referenced).
Common situations: Lockfile made read-only by git or filesystem permissions; disk full; another process deleting the lockfile mid-run; rollback after a mid-command failure.
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
- additional_artifacts must be an array in lockfile
- aube lockfile mapping keys must be strings
- aube lockfile must contain a mapping
- cannot be recreated as a directory: something else is there…
- cannot merge lockfile version
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/679c0868a834e4a2.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/lock.rs:294
let mut errors = Vec::new();
for rollback in rollbacks.into_iter().rev() {
let result = match rollback.replacement {
Some(replacement) => replacement.commit(),
None => match fs::remove_file(&rollback.path) {
Ok(()) => Ok(()),
Err(err) if err.kind() == ErrorKind::NotFound => Ok(()),
Err(err) => Err(err.into()),
},
};
if let Err(err) = result {
errors.push(format!("{}: {err:?}", display_path(&rollback.path)));
}
}
lockfile::invalidate_caches();
if errors.is_empty() {
Ok(())
} else {
bail!("{}", errors.join("\n"))
}
}
#[derive(Debug, Eq, PartialEq)]
enum LockTaskStatus {
Updated,
Unresolved,
Failed,
ProvenanceFailed,
}
fn classify_lock_result(
resolution_error: Option<String>,
error_is_fatal: bool,
applied: bool,
) -> (LockTaskStatus, Option<String>) {
if let Some(error) = resolution_error.filter(|_| error_is_fatal) {
(LockTaskStatus::Failed, Some(error))View on GitHub (pinned to 533346cc37)