{"record":{"id":"233da9ab9e1baa1a","repo":"jdx/mise","slug":"declined-nothing-was-changed","errorCode":null,"errorMessage":"declined; nothing was changed","messagePattern":"declined; nothing was changed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/system/history/replay.rs","lineNumber":505,"sourceCode":"    let mut live;\n    loop {\n        round += 1;\n        // editors may have written while the prompt was open: re-plan\n        live = live_tree(repo, tracked)?;\n        let fresh = plan(repo, exec, &live)?;\n        let changed = actionable(&fresh) != actionable(steps);\n        if changed {\n            *steps = fresh.clone();\n            miseprintln!(\"history: the working tree changed since the plan was shown:\");\n            print_plan(steps, exec, tracked)?;\n            if steps\n                .iter()\n                .any(|step| matches!(step.action, Action::Conflict(_)))\n            {\n                bail!(\"the refreshed plan has conflicts; nothing was changed\");\n            }\n            if !exec.yes && !prompt::confirm(\"history: apply the refreshed plan?\")?.is_yes() {\n                bail!(\"declined; nothing was changed\");\n            }\n        }\n        // completeness: every path about to be written or deleted that exists\n        // now must be captured, as it is now, in the protective checkpoint\n        let Some((before_id, _)) = scope.before() else {\n            bail!(\"no protective checkpoint could be taken; nothing was changed\");\n        };\n        let before = store::entry(store, before_id)?;\n        let before_tree = before\n            .checkpoint\n            .tree\n            .snapshot\n            .clone()\n            .ok_or_else(|| eyre::eyre!(\"the protective checkpoint has no content\"))?;\n        let mut missing = vec![];\n        for step in steps.iter().filter(|step| step.action.mutates()) {\n            let Some(current) = repo.restored_object_at(&live, &step.tree_path)? else {\n                continue;","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/replay.rs#L487-L523","documentation":"User-declined confirmation in history replay (apply_steps): the user answered no at the apply prompt, so the function bails with 'declined; nothing was changed' after re-planning and printing the plan. This is a normal, expected control-flow exit, not a malfunction.","triggerScenarios":"Answering 'no' (or a non-affirmative answer) to the `history: apply the refreshed plan?` prompt, i.e. when exec.yes is false and prompt::confirm does not return yes.","commonSituations":"User reviews the refreshed plan and decides not to proceed; non-interactive/CI runs where the prompt gets a non-yes answer.","solutions":["Re-run the history apply command and confirm at the prompt","Use the dry-run/plan output to review steps before confirming","No code fix is needed; this exit is by design"],"exampleFix":"// before\nmise history apply <id>   # answers prompt with 'n'\n// after\nmise history apply <id> --yes","handlingStrategy":"fallback","validationCode":"// non-interactive runs: pass --yes explicitly\nif !is_interactive && !args.contains(\"--yes\") {\n    args.push(\"--yes\");\n}","typeGuard":null,"tryCatchPattern":"// treat the bail as an intentional no-op\nmatch result {\n    Err(e) if e.to_string().contains(\"declined; nothing was changed\") => {\n        println!(\"user declined; tree untouched\");\n    }\n    other => other?,\n}","preventionTips":["Use --yes in scripts/CI to avoid interactive prompts","Review the printed plan before confirming","Treat a decline as safe: nothing was modified"],"tags":["history","replay","user-declined","prompt"],"backgroundTag":"operation-aborted-by-user","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"}