{"record":{"id":"7be037b15b76a2bc","repo":"jdx/mise","slug":"name-the-paths-to-roll-back-or-to-ref-all","errorCode":null,"errorMessage":"name the paths to roll back, or `--to <ref> --all` for everything the checkpoint covers","messagePattern":"name the paths to roll back, or `--to <ref> --all` for everything the checkpoint covers","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/replay.rs","lineNumber":115,"sourceCode":"    /// modes git cannot express, `0600` say), and for the directories\n    /// above it.\n    bits: Option<u32>,\n    dir_bits: Vec<(PathBuf, u32)>,\n}\n\n/// One checkpoint and the paths to take from it.\nstruct Target {\n    entry: Entry,\n    paths: Vec<PathBuf>,\n}\n\npub(crate) async fn rollback(req: RollbackRequest) -> Result<()> {\n    ensure_enabled()?;\n    if req.all && !req.paths.is_empty() {\n        bail!(\"choose explicit paths or `--all`, not both\");\n    }\n    if req.paths.is_empty() && !(req.to.is_some() && req.all) {\n        bail!(\n            \"name the paths to roll back, or `--to <ref> --all` for everything the checkpoint covers\"\n        );\n    }\n    if req.to.is_none() && req.all {\n        bail!(\"`--all` needs `--to <ref>`\");\n    }\n    let (store, tracked, entries) = crate::cli::dotfiles::history::open().await?;\n    let repo = store\n        .repo()\n        .ok_or_else(|| eyre::eyre!(\"rolling back requires git\"))?;\n    let live = live_tree(repo, &tracked)?;\n    let paths: Vec<PathBuf> = req\n        .paths\n        .iter()\n        .map(|path| normalize_target(path))\n        .collect();\n    for path in &paths {\n        if tracked.entry_for(path).is_none() {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/replay.rs#L97-L133","documentation":"rollback requires the request to actually name something to restore. If paths is empty and the request is not a full `--to <ref> --all` rollback, there is no defined restore target, so mise bails with guidance on the two accepted forms. This prevents silently doing nothing or guessing the scope.","triggerScenarios":"Calling rollback with no path arguments and either no --to/--all combination, e.g. `rollback` alone, `rollback --to <ref>` without --all, or `rollback --all` handled separately. Condition: req.paths.is_empty() && !(req.to.is_some() && req.all).","commonSituations":"Users run `mise bootstrap dotfiles rollback` expecting an interactive picker; scripts forget the path argument; users pass --to without --all thinking a ref alone defines scope.","solutions":["List the paths to roll back: `mise bootstrap dotfiles rollback <path>...`","Or perform a full restore: `mise bootstrap dotfiles rollback --to <ref> --all`","Run `mise bootstrap dotfiles paths` to see tracked paths first"],"exampleFix":"// before\nmise bootstrap dotfiles rollback --to abc123\n// after\nmise bootstrap dotfiles rollback --to abc123 --all","handlingStrategy":"validation","validationCode":"if (req.paths.length === 0 && !(req.to && req.all)) {\n  throw new Error(\"must specify paths, or --to <ref> --all\");\n}","typeGuard":"const hasTarget = (req: { paths: string[]; to?: string; all?: boolean }) =>\n  req.paths.length > 0 || (req.to != null && req.all === true);","tryCatchPattern":"try {\n  await rollback(req);\n} catch (e) {\n  if (String(e).includes(\"name the paths\")) {\n    console.error(\"usage: rollback <path>... | rollback --to <ref> --all\");\n  } else throw e;\n}","preventionTips":["Make at least one of paths/--to required in the CLI parser","Default to prompting for paths when none are given interactively","Document both accepted invocation forms in help output"],"tags":["cli","missing-argument"],"backgroundTag":"missing-required-flag","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}