jdx/mise · error

choose explicit paths or `--all`, not both

Error message

choose explicit paths or `--all`, not both

What it means

mise's dotfiles history rollback validates that the RollbackRequest is unambiguous before doing any git work. If the caller passes both explicit paths and the --all flag, mise cannot tell whether the user wants to restore just those paths or everything the checkpoint covers, so it refuses immediately with this bail!. This is a pure argument-validation guard at the top of rollback in src/system/history/replay.rs.

Source

Thrown at src/system/history/replay.rs:112

    from: String,
    to: String,
    /// The permission bits the checkpoint recorded for the file (only
    /// modes git cannot express, `0600` say), and for the directories
    /// above it.
    bits: Option<u32>,
    dir_bits: Vec<(PathBuf, u32)>,
}

/// One checkpoint and the paths to take from it.
struct Target {
    entry: Entry,
    paths: Vec<PathBuf>,
}

pub(crate) async fn rollback(req: RollbackRequest) -> Result<()> {
    ensure_enabled()?;
    if req.all && !req.paths.is_empty() {
        bail!("choose explicit paths or `--all`, not both");
    }
    if req.paths.is_empty() && !(req.to.is_some() && req.all) {
        bail!(
            "name the paths to roll back, or `--to <ref> --all` for everything the checkpoint covers"
        );
    }
    if req.to.is_none() && req.all {
        bail!("`--all` needs `--to <ref>`");
    }
    let (store, tracked, entries) = crate::cli::dotfiles::history::open().await?;
    let repo = store
        .repo()
        .ok_or_else(|| eyre::eyre!("rolling back requires git"))?;
    let live = live_tree(repo, &tracked)?;
    let paths: Vec<PathBuf> = req
        .paths
        .iter()
        .map(|path| normalize_target(path))

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Pass either explicit paths OR --all, never both
  2. Use explicit paths to restore specific files
  3. Use `--to <ref> --all` to restore everything the checkpoint covers

Example fix

// before
mise bootstrap dotfiles rollback ~/.zshrc --all
// after
mise bootstrap dotfiles rollback ~/.zshrc
// or
mise bootstrap dotfiles rollback --to <ref> --all
Defensive patterns

Strategy: validation

Validate before calling

if (args.all && args.paths.length > 0) {
  throw new Error("choose explicit paths or --all, not both");
}

Type guard

const isExclusive = (req: { all: boolean; paths: string[] }) =>
  !(req.all && req.paths.length > 0);

Try / catch

try {
  await rollback(req);
} catch (e) {
  if (String(e).includes("not both")) {
    req.paths = [];
    await rollback(req);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling rollback (e.g. `mise bootstrap dotfiles rollback <paths> --all` or constructing RollbackRequest with all=true and a non-empty paths vec). Any request where req.all && !req.paths.is_empty().

Common situations: Users scripting a rollback append --all to an already-specified path list; shell aliases that always add --all; users confusing --all with "include all named paths".

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/3c911987393c499a. Report an issue: GitHub.