jdx/mise · error

previous lockfiles were preserved

Error message

{detail}
previous lockfiles were preserved

What it means

`ensure_install_succeeded` re-raises a saved install failure at the end of lockfile generation. When the install failed, mise stored the detailed error text in INSTALL_FAILURE_DETAIL so that, after cleaning up, it can surface the original root cause with the reassurance that the previous lockfiles were left untouched (report.abandon() preserved them).

Solutions

  1. Read the `{detail}` portion above the suffix — it is the real root-cause error; fix that first.
  2. Retry after fixing connectivity or the backend issue; existing lockfiles are intact so a rerun is safe.
  3. If a specific tool/version fails, pin a working version or remove it from mise.toml and regenerate the lockfile.
Defensive patterns

Strategy: try-catch

Try / catch

// CI: retry once on failure; lockfiles are preserved so retry is safe
mise lock || (sleep 5 && mise lock) || exit 1

Prevention

When it happens

Trigger: Running `mise lock`/`mise install` with lockfile generation enabled when the underlying tool installation fails (network error during download, backend error, checksum failure); the detailed message stored by the failing backend is re-thrown here with the 'previous lockfiles were preserved' suffix.

Common situations: Offline or flaky network during install; registry/backend outage; corrupted cache causing a download/verification failure; unsupported target platform producing a backend error.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/557d11da652bc999. Report an issue: GitHub.

Appendix: source

Thrown at src/lockfile/generate.rs:125

                    .iter()
                    .map(|(_, error)| error.to_string())
                    .collect::<Vec<_>>()
                    .join("\n"),
            );
            record_install_failure();
        }
        errors
    }
}

pub(crate) fn record_install_failure() {
    INSTALL_FAILED.store(true, Ordering::Relaxed);
}

pub(crate) fn ensure_install_succeeded() -> Result<()> {
    if INSTALL_FAILED.load(Ordering::Relaxed) {
        if let Some(detail) = INSTALL_FAILURE_DETAIL.lock().unwrap().as_ref() {
            bail!("{detail}\nprevious lockfiles were preserved");
        }
        bail!("installation failed; previous lockfiles were preserved");
    }
    Ok(())
}

pub(crate) fn has_previous_file(config: &Config, path: &Path) -> bool {
    path.exists()
        || monorepo_lockfile_migration_paths(config)
            .iter()
            .any(|(source, target)| target == path && source.exists())
}

pub(crate) fn read_previous(config: &Config, path: &Path, upgrade: bool) -> Result<Lockfile> {
    let mut previous = Lockfile::read(path)?;
    let mut exists = path.exists();
    for (source, target) in monorepo_lockfile_migration_paths(config) {
        if target != path || !source.exists() {

View on GitHub (pinned to 533346cc37)