{"record":{"id":"f4f9188d2239680a","repo":"jdx/mise","slug":"enrollment-conflict-in-field-reconcile-reposito","errorCode":null,"errorMessage":"enrollment conflict in {field}; reconcile repository metadata before syncing","messagePattern":"enrollment conflict in (.+?); reconcile repository metadata before syncing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/manifest.rs","lineNumber":140,"sourceCode":"                self.permissions.insert(portable, *bits);\n            }\n        }\n        self.remove_unenrolled_permissions();\n        Ok(())\n    }\n\n    /// Merge enrollment by portable path rather than JSON line positions.\n    /// Independent additions and policy edits commute; deletion versus a\n    /// policy edit remains a conflict, never an implicit reenrollment.\n    pub(crate) fn merge(base: &Self, local: &Self, remote: &Self) -> Result<Self> {\n        use std::collections::BTreeMap;\n        fn choose<T: Clone + Eq>(base: &T, local: &T, remote: &T, field: &str) -> Result<T> {\n            if local == remote || remote == base {\n                Ok(local.clone())\n            } else if local == base {\n                Ok(remote.clone())\n            } else {\n                bail!(\n                    \"enrollment conflict in {field}; reconcile repository metadata before syncing\"\n                )\n            }\n        }\n        base.validate()?;\n        local.validate()?;\n        remote.validate()?;\n        if local == remote || remote == base {\n            return Ok(local.clone());\n        }\n        if local == base {\n            return Ok(remote.clone());\n        }\n        let indexed = |manifest: &Self| {\n            manifest\n                .enrollment\n                .iter()\n                .map(|entry| (entry.path.clone(), entry.clone()))","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/manifest.rs#L122-L158","documentation":"Thrown by `choose` in manifest.rs during three-way merge of enrollment metadata (`Enrollment::merge`). If a field differs between local and remote, and local also differs from base (i.e. both sides changed it), the merge is genuinely conflicted and cannot be resolved automatically; the library asks the user to reconcile repository metadata manually.","triggerScenarios":"Syncing enrollment state when both this machine and the remote repository edited the same enrollment field (e.g. variant name, target path) since the common base version.","commonSituations":"Editing dotfile enrollment on two machines and syncing both ways; rebasing history where a remote force-push rewrote metadata; merging branches that both modified the manifest.","solutions":["Manually edit the enrollment metadata to the desired value on the local side.","Pull/reset the remote metadata so one side wins, then re-apply your change and sync again.","Re-enroll the affected path to regenerate consistent metadata.","If the remote value is authoritative, reset local metadata to remote before syncing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// compare local vs remote enrollment metadata before sync;\n// resolve differing fields manually when both changed since base","typeGuard":null,"tryCatchPattern":"// on \"enrollment conflict in {field}\": stop, edit the manifest field,\n// and re-run the sync instead of retrying blindly","preventionTips":["Sync enrollment metadata from one machine at a time.","Pull remote metadata changes before making local edits.","Avoid force-pushing rewrites of dotfile repository metadata."],"tags":["merge-conflict","sync","metadata","manifest"],"backgroundTag":"conflicting-config-options","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"}