jdx/mise · error

dotfiles: cannot save the baseline

Error message

dotfiles: cannot save the baseline: {reason}

What it means

baseline() persists an initial checkpoint of tracked files into the history Store. If the store reports itself permanently unavailable (via store.unavailable()), saving the baseline is impossible and the command fails, surfacing the store's reason to the user prefixed with 'dotfiles: cannot save the baseline:'.

Solutions

  1. Read the embedded {reason} and fix it (permissions, disk space, repair the history store)
  2. Check and fix permissions on the mise data/history directory (typically ~/.local/share/mise)
  3. If the store is corrupted, remove/reinitialize the history store (accepting loss of history)
Defensive patterns

Strategy: validation

Validate before calling

store_dir="${MISE_DATA_DIR:-$HOME/.local/share/mise}/history"; test -w "$(dirname "$store_dir")" || echo 'history store directory not writable — fix permissions or disk space before dot track'

Prevention

When it happens

Trigger: Running `mise dot track` with history enabled, where Store::open() succeeds but unavailable() returns a reason — e.g. the history store directory is missing/unwritable, corrupted, or on an unsupported filesystem.

Common situations: MISE_DATA_DIR/HOME on a read-only mount; disk full; corrupted history database after an interrupted write; restrictive permissions on the mise data directory.

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@533346cc37 (2026-09-17). Data as JSON: /api/errors/bf411ae5e80248c5. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/dotfiles/track.rs:411

    }
    Ok(())
}

/// Resolve link chains using the same path representation as tracked entries.
fn resolve_symlink_source(target: &Path) -> Result<PathBuf> {
    file::atomic_write_target(target).map(|source| normalize_target(&source))
}

/// Saves the baseline checkpoint of newly tracked paths; a failure fails
/// the enrollment, since an untracked file must never look protected.
async fn baseline(tracked: &TrackedSet, declared: &[(String, PathBuf)]) -> Result<()> {
    if !crate::config::Settings::get().history.enabled {
        warn!("dotfiles: history is disabled (history.enabled = false); no baseline saved");
        return Ok(());
    }
    let store = Store::open()?;
    if let Some(reason) = store.unavailable() {
        bail!("dotfiles: cannot save the baseline: {reason}");
    }
    // A capture wrapper owns the operation lock until this child exits. It
    // reloads enrollment and explicitly saves all current tracked files in
    // its outcome (including manual entries), or during interruption recovery.
    if inside_capture()? {
        info!(
            "dotfiles: enrolled; the enclosing capture will save the baseline when the command finishes"
        );
        return Ok(());
    }
    let names = declared
        .iter()
        .map(|(key, _)| key.as_str())
        .collect::<Vec<_>>()
        .join(", ");
    let mut draft = Draft::new(Trigger::Baseline);
    draft.explicit_paths = declared
        .iter()

View on GitHub (pinned to 533346cc37)