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
- Pass either explicit paths OR --all, never both
- Use explicit paths to restore specific files
- 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
- Build CLI parsing so --all clears/forbids positional paths
- Add a unit test asserting the two options are mutually exclusive
- Show --all and <paths> as separate usage lines in help text
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
- --install takes the executable's name, not a tool id; run `m
- --name-only cannot be used with --json, --extended, or --usa
- task list options cannot be used with subcommands
- task list options cannot be used with task info
- --tool-option requires a non-empty key
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/3c911987393c499a.
Report an issue: GitHub.