{"record":{"id":"429db438ab7a5f0c","repo":"jdx/mise","slug":"conflicting-dotfile-edit-declarations-for","errorCode":null,"errorMessage":"conflicting dotfile edit declarations for {}/{}\n\n  first:\n    {}\n\n  second:\n    {}","messagePattern":"conflicting dotfile edit declarations for (.+?)/(.+?)\n\n  first:\n    (.+?)\n\n  second:\n    (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/edits.rs","lineNumber":172,"sourceCode":"                    let resolved = crate::system::files::resolve_target_arg(filter);\n                    resolved == req.path\n                }\n        })\n}\n\n/// Aggregate edit `[dotfiles]` entries across all loaded config files. Entries\n/// union global -> local, keyed by `(path, id)`; a more local config overrides\n/// an edit with the same id. Malformed entries warn and are skipped.\npub(crate) fn edits_from_config(config: &Config) -> Result<Vec<EditRequest>> {\n    let mut composed: IndexMap<String, EditRequest> = IndexMap::new();\n    for config_files in config.bootstrap_config_maps() {\n        for request in edits_from_config_files(config_files) {\n            let key = format!(\"{}\\u{0}{}\", request.path.display(), request.id);\n            if let Some(existing) = composed.get(&key) {\n                if edit_requests_match(config, existing, &request) {\n                    continue;\n                }\n                bail!(\n                    \"conflicting dotfile edit declarations for {}/{}\\n\\n  first:\\n    {}\\n\\n  second:\\n    {}\",\n                    request.path.display(),\n                    request.id,\n                    existing.origin.conflict_description(),\n                    request.origin.conflict_description(),\n                );\n            }\n            composed.insert(key, request);\n        }\n    }\n    Ok(composed.into_values().collect())\n}\n\n/// Returns whether sibling declarations produce the same file edit.\nfn edit_requests_match(config: &Config, first: &EditRequest, second: &EditRequest) -> bool {\n    first.path == second.path\n        && first.id == second.id\n        && first.op == second.op","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/edits.rs#L154-L190","documentation":"Two or more mise config files declare a dotfile edit with the same target path and id but with differing definitions. edits_from_config detects the collision while composing edits and aborts, printing both conflicting origin descriptions. Identical duplicate declarations are allowed; only genuine conflicts fail.","triggerScenarios":"Two config files (e.g. global ~/.config/mise/config.toml and a project mise.toml) both define a [dotfiles] entry with the same id targeting the same file path, with different block/line/template/comment settings.","commonSituations":"A global config and project config both manage the same shell rc entry; copying an entry between configs and editing one copy; teams sharing a config that overlaps a personal global entry.","solutions":["Rename the id in one config so the two entries no longer collide.","Point one entry at a different target path.","Make the two declarations identical if they are meant to be the same edit.","Remove the duplicate entry from the lower-priority config file."],"exampleFix":"// project mise.toml (before, conflicts with same id in global config)\n[[dotfiles]]\nid = \"zsh-alias\"\npath = \"~/.zshrc\"\nline = \"alias gs='git status'\"\n\n// after\n[[dotfiles]]\nid = \"zsh-alias-project\"\npath = \"~/.zshrc\"\nline = \"alias gs='git status'\"","handlingStrategy":"validation","validationCode":"# collect (path, id) pairs across all loaded config files and fail on differing duplicates\nseen = {}\nfor cfg in config_files:\n    for entry in cfg.dotfiles:\n        key = (str(entry.path), entry.id)\n        if key in seen and seen[key] != entry:\n            raise SystemExit(f\"conflicting dotfile edit for {entry.path}/{entry.id}\")\n        seen[key] = entry","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Namespace ids per config (e.g. prefix with project name) to avoid global/project collisions.","Avoid managing the same target file from both global and project configs.","Run `mise edits check` in CI to catch conflicts before users hit them."],"tags":["config","conflict","dotfiles","duplicate"],"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-14T05:17:10.506Z"}