{"record":{"id":"af2a777318023f56","repo":"jdx/mise","slug":"choose-only-one-resolution-for","errorCode":null,"errorMessage":"choose only one resolution for {}","messagePattern":"choose only one resolution for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/apply.rs","lineNumber":199,"sourceCode":"        };\n        blanket.extend(blanket_chosen.iter().cloned());\n    }\n\n    // Store choices without publishing or applying any part of the setup.\n    let mut sync_state = state::load(repo)?;\n    let shared = super::share::current(repo, tracked)?.objects();\n    let encrypted = super::files::encrypted_paths(repo, status.upstream_commit.as_deref())?;\n    for conflict in &status.conflicts {\n        let Some(local) = roots\n            .locate(&conflict.branch_path)\n            .path()\n            .map(Path::to_path_buf)\n        else {\n            continue;\n        };\n        if take_remote.contains(&local) || keep_local.contains(&local) {\n            if take_remote.contains(&local) && keep_local.contains(&local) {\n                bail!(\"choose only one resolution for {}\", display_path(&local));\n            }\n            // A blanket choice cannot speak for a path whose live side is not\n            // a file or symlink, and failing here would discard every other\n            // decision this pass makes. Hold that one path and keep going; a\n            // path named on the command line still reports the failure. The\n            // check belongs on this read, so a path that changed since the\n            // blanket choice was made is held too rather than aborting it.\n            // Only the path's own fault is held: a repository failure on an\n            // otherwise sound file is nobody's to fix by hand, so it stops\n            // the pass with its own error.\n            let live = match live_object(repo, &local) {\n                Ok(live) => live,\n                Err(err)\n                    if blanket_chosen.contains(&local)\n                        && err.downcast_ref::<UnusableLive>().is_some() =>\n                {\n                    blanket_held.push(err.to_string());\n                    take_remote.remove(&local);","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/sync/apply.rs#L181-L217","documentation":"During a dotfile sync apply, conflicts can be resolved with a blanket choice (take remote or keep local) plus per-path choices. If the same path appears in both the take-remote and keep-local sets, the resolution is contradictory and mise fails with this error naming the file. You must pick exactly one resolution per path.","triggerScenarios":"Invoking apply/pull where conflict-resolution flags/options put the same path into both `take_remote` and `keep_local` — e.g. passing the same path to both a '--theirs' style list and a '--ours' style list in one command.","commonSituations":"Command lines like `mise dotfiles pull --take ~/.gitconfig --keep ~/.gitconfig`; generated commands where duplicate paths land in both option groups; copy-paste errors in long path lists.","solutions":["Remove the duplicated path from one of the two resolution groups.","Decide per path: either take the remote version or keep the local one, not both.","If the lists are generated, deduplicate and validate that the two sets are disjoint before invoking.","Re-run the apply after correcting the resolution sets."],"exampleFix":"// before\nmise dotfiles pull --take-remote ~/.gitconfig --keep-local ~/.gitconfig\nError: choose only one resolution for ~/.gitconfig\n\n// after\nmise dotfiles pull --take-remote ~/.gitconfig","handlingStrategy":"validation","validationCode":"let dupes: HashSet<_> = take_remote.intersection(&keep_local).collect();\nif !dupes.is_empty() {\n  eprintln!(\"conflicting resolutions for: {:?}\", dupes);\n}","typeGuard":"fn resolutions_are_disjoint(take_remote: &HashSet<PathBuf>, keep_local: &HashSet<PathBuf>) -> bool {\n  take_remote.is_disjoint(keep_local)\n}","tryCatchPattern":null,"preventionTips":["Build the take-remote and keep-local path sets from one source of truth.","Deduplicate path lists and assert disjointness before invoking apply.","Decide a single resolution policy per path in automation."],"tags":["dotfiles","sync","conflict","cli"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}