{"record":{"id":"ced31d714113867d","repo":"jdx/mise","slug":"sync-paused-resolve-conflicts-across-the-complete","errorCode":null,"errorMessage":"sync paused: resolve conflicts across the complete repository before publication: {}","messagePattern":"sync paused: resolve conflicts across the complete repository before publication: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/publish.rs","lineNumber":55,"sourceCode":"        // line merge can conflict on independent additions or combine policy\n        // changes into invalid metadata. Validate its structured merge first.\n        if let Some(base) = &heads.base {\n            use crate::system::history::manifest::Manifest;\n            if let (Some(base), Some(ours), Some(theirs)) = (\n                Manifest::read(repo, base)?,\n                Manifest::read(repo, local)?,\n                Manifest::read(repo, remote)?,\n            ) {\n                merged = Manifest::merge(&base, &ours, &theirs)?.write(repo, &merged)?;\n                conflicts.retain(|path| path != crate::system::history::manifest::PATH);\n            }\n        }\n        let unresolved: Vec<_> = conflicts\n            .iter()\n            .filter(|path| !accepted.contains(*path))\n            .collect();\n        if !unresolved.is_empty() {\n            bail!(\n                \"sync paused: resolve conflicts across the complete repository before publication: {}\",\n                unresolved\n                    .into_iter()\n                    .map(String::as_str)\n                    .collect::<Vec<_>>()\n                    .join(\", \")\n            );\n        }\n        // Accepted choices were validated against saved, live, and remote\n        // versions. Carry their already-encrypted saved objects, not a new\n        // plaintext publication representation.\n        let overlays = conflicts\n            .into_iter()\n            .map(|path| {\n                Ok(crate::system::history::shadow::Overlay {\n                    object: repo.object_at(local, &path)?,\n                    path,\n                })","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/publish.rs#L37-L73","documentation":"When the local branch and origin diverge, mise merges their trees. Conflicting paths must be explicitly accepted by the user (recorded in the `accepted` set) before publication. If any conflict path remains unaccepted, publication is paused and the conflicting paths are listed, because publishing with unresolved conflicts would silently drop one side's changes across the complete repository.","triggerScenarios":"In publish `build`, `repo.merge_tree(local, remote)` yields conflicts; after structured manifest merging removes the manifest path conflict, any remaining conflict path not present in `accepted` triggers the bail, listing all unresolved paths comma-separated.","commonSituations":"Two machines edited the same managed file or enrollment entry offline and both pushed; the user answered some conflict prompts but skipped others; an automated publish ran non-interactively without supplying conflict resolutions.","solutions":["Run the reconcile flow (`mise bootstrap dotfiles pull`) and resolve every listed conflict path, accepting a version for each.","Re-run publication once all conflict paths are in the accepted set.","If publishing programmatically, supply resolutions for every conflicted path up front instead of leaving any unresolved."],"exampleFix":"// before: publish with only some conflicts accepted\naccepted = {\"~/.config/mise/mise.toml\"}\nmise bootstrap dotfiles publish   # ~/.bashrc still unresolved -> paused\n// after\nmise bootstrap dotfiles pull      # resolve ~/.bashrc (and any others)\nmise bootstrap dotfiles publish","handlingStrategy":"validation","validationCode":"const { conflicts } = await mergeTree(local, remote);\nconst unresolved = conflicts.filter((p) => !accepted.has(p));\nif (unresolved.length > 0) {\n  throw new Error(`resolve conflicts before publication: ${unresolved.join(\", \")}`);\n}","typeGuard":"const allResolved = (conflicts, accepted) => conflicts.every((p) => accepted.has(p));","tryCatchPattern":"try {\n  await publish();\n} catch (e) {\n  const m = String(e.message).match(/before publication: (.+)$/);\n  if (m) {\n    const paths = m[1].split(\", \");\n    for (const p of paths) await promptAndAccept(p);\n    await publish();\n  } else throw e;\n}","preventionTips":["Always run the interactive reconcile and resolve every listed path, not just some.","Pull regularly so divergence (and thus conflicts) stays small.","When publishing from scripts, pre-populate resolutions for every conflicted path."],"tags":["sync","git","merge-conflict","publication"],"backgroundTag":"merge-conflicts-unresolved","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}